软件体系结构-KWIC索引系统

2023-11-15

引言

KWIC作为一个早年间在ACM的Paper提出的一个问题,被全世界各个大学的软件设计课程奉为课堂讲义或者作业的经典。(From Wiki,FYI,D. L. Parnas uses a KWIC Index as an example on how to perform modular design in his paper “On the Criteria To Be Used in Decomposing Systems into Modules” - Available as ACM Classic Paper)
在这里插入图片描述
这道题旨在深入理解模块和组件之间的划分,解法有多种,通过不同的解决方案来体会软件设计的体系结构。

解决方案1:使用共享数据的主程序/子程序

解法:分解为四个组件:输入、移位、排列和输出,主程序依次对他们进行调用,数据通过共享存储在组件间共享,组件与数据之间读写不受约束,由主程序协调保证读写顺序。

优劣

  • 直观、算法隔离
  • 应对数据变化能力弱
  • 可复用性差
    共享数据
    在这里插入图片描述
#include <iostream>
#include <vector>
#include <algorithm>
#include <fstream>
#include <cstdlib>
#include <string>
#include <sstream>
using namespace std;
vector<string> lineList;
void inputStr()
{
    ifstream inFile("D:/km.txt", ios::in);
    if (!inFile)
    {
        cerr << "File could not be open file" << endl;
        exit(1);
    }
    string str;
    while (getline(inFile, str, '\n'))
    {
        lineList.push_back(str);
    }
}
void circshift()
{
    int i;
    vector<string> list = lineList;
    for (i = 0; i < list.size(); i++)
    {
        string line = list[i];
        vector<string> st;
        istringstream ss(line);
        while (!ss.eof())
        {
            string x;
            getline(ss, x, ' ');
            st.push_back(x);
        }
        int j = 0;
        while (j < st.size() - 1)
        {
            string tmp = st[0] + " ";
            st.erase(st.begin());
            st.push_back(tmp);
            string t = "";
            for (int k = 0; k < st.size(); k++)
                t += st[k] + " ";

            lineList.push_back(t);

            j++;
        }
    }
}
void sort()
{

    sort(lineList.begin(), lineList.end());
}
void output()
{
    vector<string>::iterator it;
    for (it = lineList.begin(); it != lineList.end();it++)
        cout << *it << endl;
}
int main()
{
    inputStr();
    circshift();
    sort();
    cout << endl
         << endl;
    output();
    return 0;
}

解决方案2:抽象数据类型/面向对象风格

解法:对比方案一,分为五个模块,数据不再共享,而是相反做了接口隔离,将各个功能模块分开设计,并且利用权限控制保证了封装的特性,系统的扩展性和封装性增强,是个基本的面向对象方案。
优劣

  • 数据的变化可以在各子模块内更改
  • 支持复用
  • 不适合增加功能
    在这里插入图片描述
// C++参考代码:
#include <iostream>
#include <vector>
#include <algorithm>
#include <fstream>
#include <cstdlib>
#include <string>
#include <sstream>
using namespace std;

class Input
{
private:
    vector<string> lineList;

public:
    vector<string> getLineTxt()
    {
        return lineList;
    }

    void inputLine(string fileName)
    {
        ifstream inFile(fileName, ios::in);

        if (!inFile)
        {
            cerr << "File could not be open file" << endl;
            exit(1);
        }
        string str;
        while (getline(inFile, str, '\n'))
        {
            lineList.push_back(str);
        }
    }
};

class circshift
{
private:
    vector<string> kwList;
    vector<string> lineList;

public:
    circshift(vector<string> lineList)
    {
        this->lineList = lineList;
    }

    vector<string> getLineList()
    {
        return lineList;
    }
    vector<string> getKwList()
    {
        return kwList;
    }

    void cirShift()
    {
        int i;

        for (i = 0; i < lineList.size(); i++)
        {
            string line = lineList[i];
            vector<string> st;

            istringstream ss(line);
            while (!ss.eof())
            {
                string x;
                getline(ss, x, ' ');
                st.push_back(x);
            }

            int j = 0;
            while (j < st.size())
            {
                string tmp = st[0] + " ";
                st.erase(st.begin());
                st.push_back(tmp);
                string t = "";
                for (int k = 0; k < st.size(); k++)
                    t += st[k] + " ";
                kwList.push_back(t);

                j++;
            }
        }
    }
};

class lineSort
{
private:
    vector<string> kwList;

public:
    lineSort(vector<string> kwList)
    {
        this->kwList = kwList;
    }
    vector<string> getKwList()
    {
        return kwList;
    }
    void linsort()
    {

        sort(kwList.begin(), kwList.end());
    }
};

class output
{
private:
    vector<string> kwList;

public:
    output(vector<string> kwList)
    {
        this->kwList = kwList;
    }

    void show()
    {
        vector<string>::iterator it;

        for (it = kwList.begin(); it != kwList.end(); it++)
        {
            cout << *it << endl;
        }
    }
};

int main(void)
{
    Input in;
    in.inputLine("D:/km.txt");
    circshift cshift(in.getLineTxt());
    cshift.cirShift();
    lineSort linesort(cshift.getKwList());
    linesort.linsort();
    output out(linesort.getKwList());
    out.show();
    return 0;
}

解决方案三:基于事件通知的方案/响应式

解法:类似方案一,但数据更抽象,而不是暴露数据格式,数据被修改时,隐式调用计算。
基于事件通知的系统中的各个功能并不是直接被调用的,而是通过组建通知或广播事件信息而触发的。其他组件可以通过注册一个与某个事件通知相关联的过程而与其发生联系。

优劣

  • 较容易支持新增功能、新增模块
  • 计算与数据隔离
  • 支持复用
  • 比较难改变隐式调用的顺序
  • 由于数据驱动通常导致空间占用问题
    在这里插入图片描述
    一般这样的方案有两种设计,一个是系统有一个分立出来的事件中心,专门负责接收所有传来的信息,并且将它们分发给系统的其他组件,它可以是广播,可以是针对某些特定事件而设定特定的反应。

解决方案四:基于管道的方案

解法:在基于管道的方案中,每个组件都会有一组输入流和一组输出流,一个组件读入,然后处理后送出到下一个组件上。这个组件一般称为filter。连接器则称为pipes。filter之间不能有数据共享,并且彼此相互独立。
管道由一系列过滤器组成,通过数据流连接
分布式,每个过滤器只要有要计算的数据就可以运行
过滤器之间的数据共享严格限于在管道上传输的数据
优劣

  • 直观
  • 支持重用,因为每个过滤器都可以独立运行
  • 通过插入新的过滤器,容易新增功能(删除行除外
  • 端口之间数据复制传递,有性能损耗。

在这里插入图片描述

#include <iostream>
#include <vector>
#include <algorithm>
#include <fstream>
#include <cstdlib>
#include <string>
#include <sstream>
using namespace std;

vector<string> inputStr(string address)
{
    vector<string> lineList;
    ifstream inFile(address, ios::in); // ifstream  inFile("D:/km.txt", ios::in);

    if (!inFile)
    {
        cerr << "File could not be open file" << endl;
        exit(1);
    }

    string str;

    while (getline(inFile, str, '\n'))
    {
        lineList.push_back(str);
    }

    return lineList;
}

vector<string> circshift(vector<string> &lineList)
{
    int i;
    vector<string> list = lineList;

    for (i = 0; i < list.size(); i++)
    {
        string line = list[i];
        vector<string> st;

        istringstream ss(line);
        while (!ss.eof())
        {
            string x;
            getline(ss, x, ' ');
            st.push_back(x);
        }
        int j = 0;
        while (j < st.size() - 1)
        {
            string tmp = st[0] + " ";
            st.erase(st.begin());
            st.push_back(tmp);

            string t = "";
            for (int k = 0; k < st.size(); k++)
                t += st[k] + " ";
            lineList.push_back(t);

            j++;
        }
    }

    return lineList;
}

vector<string> sort(vector<string> &lineList)
{

    sort(lineList.begin(), lineList.end());
    return lineList;
}

void output(vector<string> &lineList)
{
    vector<string>::iterator it;

    for (it = lineList.begin(); it != lineList.end(); it++)
        cout << *it << endl;
}
int main()
{
    string address = "D:/km.txt";
    vector<string> stringList;
    stringList = inputStr(address);
    stringList = circshift(stringList);
    stringList = sort(stringList);
    cout << endl
         << endl;
    output(stringList);

    return 0;
}

总结

KWIC索引系统是软件体系结构研究领域的一个经典案例,它为我们提供了一个理解软件架构设计原则和实践的框架。它的价值在于,可以帮助我们在设计大型软件系统时,更好地平衡复杂性、灵活性和性能,帮助我们更好地理解和应用软件体系结构设计原则。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

软件体系结构-KWIC索引系统 的相关文章

  • 正确的认识乱码与编码

    文章目录 编码的本质 乱码的几个例子及思考解决方案 浏览器输入到后端乱码 后端返回浏览器乱码 java 枚举类乱码 数据库存储乱码 Linux系统显示乱码 总结 编码的本质 编码将内存字节作用于磁盘文件或者网络文件的过程 是将磁盘文件 网络
  • 系统开发与运行

    系统开发与运行 系统分析与设计 需求分析 需求工程 结构化分析与设计 测试基础知识 系统运行与维护 软件架构介绍 系统分析概述 系统分析是一种问题求解技术 它将一个系统分解成各个组成部分 目的是研究各个部分如何工作 交互 以实现其系统目标
  • 软件工程:(四)概要设计

    一 定义 概要设计是一个设计师根据用户交互过程和用户需求来形成交互框架和视觉框架的过程 其结果往往以反映交互控件布置 界面元素分组以及界面整体板式的页面框架图的形式来呈现 这是一个在用户研究和设计之间架起桥梁 使用户研究和设计无缝结合 将对
  • 软件工程-第七章-实现

    软件工程 第七章 实现 7 实现 7 2 软件测试基础 7 2 3 测试方法 7 2 4 测试步骤 7 3 单元测试 7 3 2 代码审查 7 4 集成测试 7 4 1 自顶向下集成 7 4 2 自底向上集成 7 5 确认测试 7 5 3
  • 软件设计七大原则

    文章目录 一 开闭原则 定义 实现方法 二 里氏替换原则 定义 实现方法 三 依赖倒置原则 定义 实现方法 四 单一职责原则 定义 实现方法 五 接口隔离原则 定义 实现方法 六 迪米特法则 定义 实现方法 七 合成复用原则 定义 实现方法
  • idea插件生成用例图、时序图、类图、活动图

    给大家推荐一个idea生成用例图 时序图等的神器 PlantUML 最近软件工程要结课了 结课报告要附加用例图 时序图 类图 活动图等 类图我首先就想到可以用idea生成 嘿嘿 可惜忘了怎么用 搜着搜着 突然发现 idea生成时序图 用例图
  • 软件工程第五章习题

    软件工程第五章习题 1 为每种类型的模块耦合举一个具体例子 2 为每种类型的模块内聚举一个具体例子 1 为每种类型的模块耦合举一个具体例子 只需要答出什么模块和例子即可 一共5个 数控特环内 数据耦合 两个模块之间通过参数交换信息 信息仅为
  • 软件设计师--结构化开发

    结构化开发 耦合 真题 内聚 真题 设计原则 真题 系统文档 真题 数据流图 数据流图基本数据元素 外部实体 数据存储 加工 数据流 父图子图平衡 加工既要有输入数据流也要有输出数据流 数据守恒 真题 数据字典 真题 杂题精选 耦合 真题
  • 软工导论知识框架(五)面向对象方法学

    传统软件工程方法学适用于中小型软件产品开发 面向对象软件工程方法学适用于大型软件产品开发 一 四要素 对象 类 继承 传递消息实现通信 二 概念 1 对象 具有相同状态的一组操作的集合 对状态和操作的封装 2 类 对具有相同状态和相同操作的
  • 软件工程——第7章实现知识点整理

    本专栏是博主个人笔记 主要目的是利用碎片化的时间来记忆软工知识点 特此声明 文章目录 1 实现由哪两个部分组成
  • 系统架构设计师-数据库系统(1)

    目录 一 数据库模式 1 集中式数据库 2 分布式数据库 二 数据库设计过程 1 E R模型 2 概念结构设计 3 逻辑结构设计 三 关系代数 1 并交差 2 投影和选择 3 笛卡尔积 4 自然连接 一 数据库模式 1 集中式数据库 三级模
  • 【论文阅读-ICSE-2021】CodeShovel: 构造方法级别上的源代码历史信息 Constructing Method-Level Source Code Histories

    CodeShovel Constructing Method Level Source Code Histories Conference ICSE 2021 Github https github com ataraxie codesho
  • 服务计算:简单的web程序

    CloudGo 框架选择 看了go的一些框架如beego和iris觉得挺好的 本来想用 但是虚拟机出了点问题装不成 windows上装成了没ab指令 所以使用官方的net http库做简单的实验 看完beego和iris的特性我还是比较想用
  • 海南大学软件工程原理835考研

    海南大学835考研 2023考研已经落幕 我从2022 05 2023 03 用了大概一年的时间 目前已被海南大学计算机科学与技术学院录取 下面来谈谈我的学习感想 希望能给大家带来帮助 对于专业课 我用的是张海藩的软件工程导论第六版 和史济
  • WMS系统出库扫描:提升仓储管理效率与准确性

    WMS系统中的出库扫描功能是关键环节之一 它通过扫描物料或货物的条形码或二维码 实现实时 准确地记录和更新库存信息 一 WMS系统出库扫描的重要性 1 实现库存准确性 通过出库扫描 WMS系统能够准确记录物料或货物的出库信息 实时更新库存数
  • 68 | 软件工程的宏观视角

    软件工程 今天开始 我们进入第六章 谈谈软件工程 我理解的架构师的职责其实是从软件工程出发的 也许大家都学过软件工程 但如果我们把软件工程这门课重新看待 这门学科到底谈的是什么 是软件项目管理的方法论 无论如何 软件工程是一门最年轻的学科
  • 嵌入式培训机构到底怎么选?培训了能找到工作吗

    嵌入式作为一种广泛应用于企业级开发的编程语言 对于想要从事软件开发行业的人来说 掌握嵌入式技能是非常重要的 而参加嵌入式培训机构是一个快速提升技能的途径 然而 很多人可能会担心 参加嵌入式培训了能找到工作吗 如何选择靠谱的嵌入式培训机构 要
  • 【软件测试】学习笔记-脚本与数据的解耦 + Page Object模型

    本篇文章介绍GUI测试中两个非常重要的概念 测试脚本和数据的解耦 以及页面对象 Page Object 模型 测试脚本和数据的解耦 GUI自动化测试适用的场景 尤其适用于需要回归测试页面功能的场景 如果在测试脚本中硬编码 hardcode
  • 深入了解 Python MongoDB 操作:排序、删除、更新、结果限制全面解析

    Python MongoDB 排序 对结果进行排序 使用 sort 方法对结果进行升序或降序排序 sort 方法接受一个参数用于 字段名 一个参数用于 方向 升序是默认方向 示例 按名称按字母顺序对结果进行排序 import pymongo
  • 掌握 C# 变量:在代码中声明、初始化和使用不同类型的综合指南

    C 变量 变量是用于存储数据值的容器 在 C 中 有不同类型的变量 用不同的关键字定义 例如 int 存储整数 没有小数点的整数 如 123 或 123 double 存储浮点数 有小数点 如 19 99 或 19 99 char 存储单个

随机推荐

  • C语言-程序设计基础-常量、变量、标识符

    2 1常量 变量 标识符 2 1 1标识符 定义 标识符就是一个名称 用来表示变量 常量 函数以及文件等名称 格式 合法的标识符由字母 大 小写均可 数字和下划线组成 并且必须以字母或下划线开头 注 1 C语言是一种对大小写敏感的语言 所以
  • postgres格式化时间_在postgresql数据库中判断是否是数字和日期时间格式函数操作...

    在编写GreenPlum函数的过程中 遇到要判断字符串是否是数字和日期格式的情况 基于GreenPlum和postgresql的亲缘关系 找到了下面两个函数 1 判断字符串是否是数字 CREATE OR REPLACE FUNCTION i
  • CVPR2017-目标检测相关

    1 Speed accuracy trade offs for modern convolutional object detectors 其主要考虑三种检测器 Faster RCNN R FCN SSD 作为元结构 三种CNN网络 VGG
  • Python 处理 ini 文件 的模块

    Python 处理 ini 文件 的模块 1 ini 文件 2 configparser 模块 2 1 语法介绍 2 2 操作示例 1 ini 文件 ini 文件是 Initialization File 的缩写 即初始化文件 ini 文件
  • 面向安全数据包分析

    网络安全是一个十分重要的话题 但是它同时也是一个十分复杂的问题 各种针对网络的攻击手段层出不穷 对于网络的守护者来说 将这些手段进行分类是一个十分棘手的工作 网络安全是一个非常复杂的问题 所以我们按照TCP IP分层的方式 对网络中的常见攻
  • 浅谈测试开发岗位

    一 测试开发的概念与需求 测试开发 通常也被称为自动化测试 是一个涵盖了从测试设计 开发 执行和结果分析等一系列活动的职位 在软件开发的生命周期中 测试开发起着至关重要的作用 其主要目标是确保软件的质量和性能达到预期的标准 测试开发工程师通
  • MySQL查看当前数据库视图-SQL语句

    引言 查询语句为 show full tables where table type 可查询当前数据库表 一 创建一个视图 创建视图 create view v stu as 视图内容 连接的一个表 select name from t s
  • Stm32待机模式的进入与唤醒

    1 基础介绍 1 1 单片机的 低功耗模式 像是手机的待机模式 不同于正常运行模式 处于一种省电省资源的状态 1 2 在运行情况下 HCLK为cpu提供时钟 cortex m3内核执行程序的代码 如果处于中断事件的等待时 可以进入低功耗模式
  • 基于R语言分析身高与体重的相关性分析

    本博文源于暨南大学的 多元数据统计分析及R语言建模 旨在讲述身高与体重相关性分析 在概率论与数理统计课程中 两个变量之间协方差的标准化 因此先要熟悉并回忆公式 套用在R语言即可 例子 分析身高 kg 与体重 cm 的相关性 gt x1 c
  • 小心情

    好久没写博客了 总结下现在的自己 还是依旧那么的 情绪控 变化那么快 有时 都受不了自己的 坏脾气 学习再也没像原来的那么卖力 有那么点的小颓废 实验室布置的任务有那么点的小懈怠 一切都没有进展 生活依旧那么平淡 却也没有自己想要的那种安逸
  • linux内核对于指令异常的处理

    1 处理流程 以arm64来介绍一下流程 如果在用户层发生指令异常时 首先进入入口el0 undef arch arm64 kernel entry s el0 undef Undefined instruction enable inte
  • Jina 3.14 版本发布!支持独立部署Executor

    Jina 是一个 MLOps 框架 赋能开发者在云上构建多模态 跨模态的应用程序 Jina 能够将 PoC 提升为生产就绪服务 基础设施的复杂性交给 Jina 开发者能够直接轻松使用高级解决方案和云原生技术 GitHub https git
  • mysql免安装版的下载与安装

    下载 打开 https www mysql com downloads 1 点击该项 2 进去后点击 3 到了真正的下载页面 选择平台 选择版本 安装版和免安装版 下载 4 我现在下载免安装版的 Windows x86 64 bit ZIP
  • Python基础-将变量的值作为变量名

    使用场景 linux unix磁盘文件系统实时使用情况动态收集 每一台机器挂载的文件系统名字有可能都不相同 就算同一台机器不同时间段挂载的文件系统也会不同 我们需要动态收集文件系统名 将变量的值作为变量 定义为文件系统的名 语法基础 gt
  • java如何将字符串存入到数组中

    方法一 public static void main String args 定义一个字符串 String str browser 定义一个字符数组 char array new char 100 for int i 0 i lt str
  • liberity 添加信赖的https证书到key.jks

    业务场景 定时任务批量推送数据到第三方接口 请求地址为https 域名 测试环境测试之后 出现证书认证问题 不能正常推送数据 定时任务部署在 websphere liberty中 出现问题之后在java的Java jdk 1 8 jre l
  • webpack 压缩图片

    问题描述 vue正常打包之后一些图片文件很大 使打包体积很大 通过image webpack loader插件可将大的图片进行压缩从而缩小打包体积 参考 点这里 解决方法 一定要用cnpm安装 cnpm i image webpack lo
  • 数据结构Java实现05----栈:顺序栈和链式堆栈

    本文转载至 http www cnblogs com smyhvae p 4789699 html 一 堆栈的基本概念 堆栈 也简称作栈 是一种特殊的线性表 堆栈的数据元素以及数据元素间的逻辑关系和线性表完全相同 其差别是线性表允许在任意位
  • 数据库的优化方案

    1 优化索引 SQL语句 分析慢查询 2 设计表的时候严格根据数据库的设计凡事来设计数据库 3 使用缓存 把经常访问到的数据且不经常变化的数据放在缓存中 节约磁盘IO 4 优化硬盘 采用SSD 使用磁盘队列技术 5 采用MySQL内部自带的
  • 软件体系结构-KWIC索引系统

    引言 KWIC作为一个早年间在ACM的Paper提出的一个问题 被全世界各个大学的软件设计课程奉为课堂讲义或者作业的经典 From Wiki FYI D L Parnas uses a KWIC Index as an example on