标签: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