标签:func 体系 属性 ima append 必须 read source echo
一、实验目的
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 运行结果

五、实验总结
进一步理解不同体系结构风格的具体内涵,具体实践学习体系结构风格。
标签:func 体系 属性 ima append 必须 read source echo
原文地址:http://www.cnblogs.com/lvyt/p/7859316.html