130242014017-蔡志峰-第3次实验

Posted zz_theDawn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了130242014017-蔡志峰-第3次实验相关的知识,希望对你有一定的参考价值。

一、实验目的

1.理解不同体系结构风格的具体内涵。

2.学习体系结构风格的具体实践。

二、实验环境

硬件: win10

软件:javascript

三、实验内容

“上下文关键字”KWIC(Key Word in Context,文本中的关键字)检索系统接受有序的行集合:每一行是单词的有序集合;每一个单词又是字母的有序集合。通过重复地删除航中第一个单词,并把它插入行尾,每一行可以被“循环地移动”。KWIC检索系统以字母表的顺序输出一个所有行循环移动的列表。

尝试用不同的策略实现这个系统。选择2-3种体系结构风格来实现。

四、实验步骤:

     要求写具体实现代码,并根据实际程序,画出程序的总体体系结构图和算法结构图,以及运行结果截图。

1.采用管道/过滤器的风格

1.1、体系结构图:

  

1.2简述体系结构各部件的主要功能,实现思想。

  上述的管道/过滤器方法,将问题分解为多种过滤器的协作, 并由全局的管道对象来调度过滤行为。

 

  Filter: 管道类的抽象基类,为每个管道对象提供数据校验, 数据处理以及设置下一个管道的接口与属性

  pipe:全局的管道对象,提供过滤器的插入,初始数据的读入与最终的输出

  StamentsSorterFilter:为一组字符串数组按字母表排序,输出对应的排序结果

  WordsMoverFilter:行循环移动过滤器,输入一个语句,输出该语句首单词循环移动的结果

1.3写出主要的代码

  

const fs = require("fs");
/**
* kwic程序设计
* 管道/过滤器风格
* 输入策略: 从文件中读取
* 行移动策略: 每输入一行移动一次
* 行存储策略: 显式存储
*/

/**
* 过滤器基对象 
* 为过滤器提供链表节点属性
*/
class Filter {
constructor(nextFilter) {
this._checkOptions(nextFilter);
this.next = nextFilter;
}
_checkOptions(nextFilter) {
if (!nextFilter instanceof Filter) {
throw new TypeError("下一个过滤器必须是过滤器类型!");
}
}
checkInput() {
throw new ReferenceError("这是一个抽象方法");
}
handle(input) {
throw new ReferenceError("这是一个抽象方法");
}
}

class WordsMoveFilter extends Filter {
constructor() {
super();
}
checkInput(data) {
const isStrArr = data.every(item => {
return typeof item === "string";
});

if( !isArray ){
throw new TypeError("数据格式不满足处理条件"); 
}
}
handle(data) {
this.checkInput(data);

let results = [];
for(let i = 0, len = data.length; i < len; i++){

let line = data[ i ];
results.push( line );

let words = line.trim().replace(/\\s+/g, " ").split(" ");
let wordCtn = words.length;

while( wordCtn > 1){
words.push(words.shift());
results.push(words.join(" "));
wordCtn--;
}
}

return results;
}
}

class StatementsSorterFilter extends Filter {
constructor() {
super();
}
checkInput(data) {
const isStrArr = data.every(item => {
return typeof item === "string";
});

if( !isStrArr ){
throw new TypeError("数据格式不满足处理条件"); 
}
}
handle(data) {
this.checkInput(data);
let results = [];
results = data.sort();
return results;
}
}

/**
* 管道对象
* 本质上是个单链表
*/
const pipe = {
filterHead: new Filter(),
length: 0,
insertFilter(newFilter, index) {

if (index < 0 || index > this.length) {
throw new RangeError("index超出合理的范围");
}

let filter = this.filterHead;
while (filter.next && index > 0) {
filter = filter.next;
index--;
}

newFilter.next = filter.next;
filter.next = newFilter;

this.length++;
},
appendFilter(filter) {
this.insertFilter(filter, this.length);
},
readDataSouceFromFile(fileName) {

const dataSource = [];

return new Promise(function (resolve, reject) {
const stream = fs.createReadStream(fileName);
stream.on("data", data => {
dataSource.push(data.toString());
});

stream.on("end", function () {
resolve(dataSource);
});
});
},
startFilterAndOuput(dataSource) {
let filter = this.filterHead;
let data = dataSource;

while (filter.next && filter.handle) {
data = filter.handle(data);
filter = filter.next;
}
}
}

pipe.appendFilter(new WordsMoveFilter());
pipe.appendFilter(new StatementsSorterFilter())
pipe.readDataSouceFromFile("example.txt").then(pipe.startFilterAndOuput);

 

  

1.4显示结果:

  

 

 

2. 面向对象设计,模块之间通过接口通信

2.1 体系结构图

   

 

  2.2 主要构件及其思想

上述的面对对象设计,模块之间通过接口通信主要将系统分为输入,输出, 行移动, 语句排序这几个模块,每个模块维护自己的数据结构,由主控制类来调度他们的行为。

Input : 输入类,负责从文件中读入语句组,为外界提供访问自身输入结构的接口

Mover:行移动类, 负责对自身的语句组执行行移动操作, 语句组数据从通过输入类的接口获得

Sorter :排序类, 负责对自身的语句组执行排序操作, 语句组通过访问行移动类的接口获得

Output: 输出类,负责将自身的语句组输出

 

  2.3核心代码

 

 

const fs = require("fs");

/**
* kwic程序设计
* 面向对象, 对象之间通过接口来访问数据
*/

class Input {
constructor() {
this.statements = [];
}
read(filename) {
const stream = fs.createReadStream(filename);

stream.on("data", data => {
let statement = data.toString().trim().replace(/\\s+/g, " ");
this.statements.push(statement);
});
}
}

class Mover {
constructor() {
this.statements = [];
this.movedStatements = [];
}
setStatements(statements) {
this.statements = statements;
}
moveTheStatementWords() {

for (let i = 0, len = this.statements.length; i < len; i++) {

let line = this.statements[i];
this.movedStatements.push(line);

let words = line.trim().replace(/\\s+/g, " ").split(" ");
let wordCtn = words.length;

while (wordCtn > 1) {
words.push(words.shift());
this.movedStatements.push(words.join(" "));
wordCtn--;
}
}
}
}

class Sorter {
constructor() {
this.statements = [];
}
setStatements( statements ){
this.statements = statements;
}
sortStatements() {
this.statements = this.statements.sort()
}
}

class Output {
constructor() {
this.results = [];
}
setSortedStatements(statements) {
this.results = statements;
}
echoResult() {
this.results.forEach((item) => {
console.log(item);
});
}
}

class Kwic {
constructor() {
this.input = new Input();
this.output = new Output();
this.sorter = new StatementsSorter();
this.mover = new StatementWordsMover();
}
run() {
this.input.read();
this.mover.setStatements(this.input.getStatements());
this.mover.movedStatements();
this.sorter.setSortedStatements(this.mover.getStatements());
this.sorter.sortStatements();
this.output.setStatements(this.sortStatements.getStatements());
this.ouput.echoResult();
}
}

let kwic = new Kwic();
kwic.run();

 

  2.4 运行结果

 

  

五、实验总结

  

  进一步理解不同体系结构风格的具体内涵,具体实践学习体系结构风格。

 

以上是关于130242014017-蔡志峰-第3次实验的主要内容,如果未能解决你的问题,请参考以下文章

130242014053 “电商系统某功能模块”需求分析与设计实验课小结

科大奥瑞物理实验——测量锑化铟片的磁阻特性

操作系统第3次实验报告:管道

Linux内核设计第二周学习总结 完成一个简单的时间片轮转多道程序内核代码

130242014048--《电商系统某功能模块》的需求分析与设计的课程小结

嵌入式软件设计第9次实验报告