KWIC—Implicit Invocation

article/2025/6/25 13:02:58

image-20250531212211161

KWIC—Implicit Invocation

✏️ KWIC—Implicit Invocation


文章目录

  • KWIC—Implicit Invocation
    • 📝KWIC—Implicit Invocation
      • 🧩KWIC
      • 🧩核心组件
      • 🧩ImplementationScheme
      • ⚖️ 隐式调用 vs 显式调用对比
    • 🌟 总结

📝KWIC—Implicit Invocation

🧩KWIC

KWIC(Key Word In Context)系统是一个经典的软件架构案例,本实现采用了隐式调用(Implicit Invocation)架构风格。该系统的主要功能是对输入文本进行循环移位并按字母顺序排序输出。

传统的 KWIC 实现通常通过函数调用顺序显式连接模块,例如:输入 → 循环移位 → 排序 → 输出。但这种方式导致模块间耦合度高、可维护性差。

在本系统中,模块间不直接调用,而是通过事件驱动机制进行通信:

  • 每当有新输入,Inputer 会广播 InsertToTextLineEvent
  • CircularShifter 监听此事件,进行移位操作
  • 移位完成后,广播 InsertToTextLinesEvent
  • Alphabetizer 接收到该事件后执行排序与输出

这种事件触发机制大大增强了系统的灵活性与扩展性

模块职责说明
Inputer负责读取文件并逐行生成事件
CircularShifter监听输入事件,对每一行生成所有移位组合
Alphabetizer监听移位事件,对所有移位结果按字母序排序
Outputer接收最终结果,负责控制台打印与文件输出
EventManager管理监听器注册、注销及事件广播

🧩核心组件

  1. 事件管理器(EventManager):作为系统的中枢,负责协调各组件间的通信
    • 维护监听器列表
    • 提供监听器注册/注销方法
    • 实现事件广播机制
  2. 输入处理(Inputer):负责读取输入文件
    • 逐行读取文本内容
    • 触发文本行插入事件
  3. 循环移位器(CircularShifter):处理文本的循环移位
    • 监听文本行插入事件
    • 为每行生成所有可能的移位组合
    • 触发文本行集合插入事件
  4. 字母排序器(Alphabetizer):对移位结果进行排序
    • 监听移位完成事件
    • 对结果进行字母序排序
    • 输出最终结果
9668c0409ca3ffdb9c2116710fb5a98

🧩ImplementationScheme

A third way for styles to
be combined is to
elaborate one level of
package com.wy;
import java.io.IOException;
import java.util.Collections;public class Alphabetizer implements KWICListener{private TextLines textlines=null;@Overridepublic void handleEvent(KWICEvent event) {if(event instanceof InsertToTextLinesEvent){textlines=((CircularShifter) event.getSource()).getTextLines();Collections.sort(textlines.getLineList());try {Outputer.println(textlines);} catch (IOException e) {e.printStackTrace();}}}
}
package com.wy;
import java.util.ArrayList;public class CircularShifter implements KWICListener{private TextLines textlines=null;@Overridepublic void handleEvent(KWICEvent event) {if(event instanceof InsertToTextLineEvent){TextLine textline=((Inputer) event.getSource()).getTextLine();int number_of_lines=textline.numberOfLines();ArrayList<ArrayList> exlist=new ArrayList<ArrayList>(0);ArrayList<String> inlist=new ArrayList<String>(0);for(int i=0;i<number_of_lines;i++){for(int j=0;j<textline.numberOfWords(i);j++){if(j==0)  {inlist.add(textline.getLine(i));}else {inlist.add(textline.shiftwords(i));}}exlist.add(inlist);inlist=new ArrayList<String>(0);}textlines=new TextLines();for(int i=0;i<number_of_lines;i++){for(int j=0;j<exlist.get(i).size();j++){textlines.addLine((String)exlist.get(i).get(j));}}InsertToTextLinesEvent ittles=new InsertToTextLinesEvent(this);EventManager.broadcast(ittles);}}public TextLines getTextLines(){return textlines;}
}
package com.wy;
import java.util.ArrayList;
import java.util.List;public class EventManager {// 监听器列表private static List<KWICListener> listenerList = new ArrayList<KWICListener>();// 监听器注册方法public static void addListener(KWICListener listener) {listenerList.add(listener);}// 监听器注销方法public static void removeListener(KWICListener listener) {listenerList.remove(listener);}// 事件广播方法public static void broadcast(KWICEvent event) {for(KWICListener listener : listenerList)listener.handleEvent(event);}
}
package com.wy;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;public class Inputer {private TextLine textline=null;public Inputer(FileReader fr) throws IOException {input(fr);}public void input(FileReader fr) throws IOException{BufferedReader br=new BufferedReader(fr);textline=new TextLine();while(br.ready()){textline.addLine(br.readLine());InsertToTextLineEvent ittle=new InsertToTextLineEvent(this);EventManager.broadcast(ittle);}}public TextLine getTextLine(){return textline;}
}
package com.wy;
public class InsertToTextLineEvent extends KWICEvent{public InsertToTextLineEvent(Object source) {super(source);}
}
package com.wy;public class InsertToTextLinesEvent extends KWICEvent{public InsertToTextLinesEvent(Object source) {super(source);}
}
package com.wy;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;public class KWIC {public static void main(String args[]) throws IOException{EventManager.addListener(new CircularShifter());EventManager.addListener(new Alphabetizer());FileReader fr=new FileReader("D:\\TXJG\\KWICY\\src\\main\\resources\\input.txt");Inputer inputer=new Inputer(fr);}
}
package com.wy;
import java.util.EventObject;public class KWICEvent extends EventObject{public KWICEvent(Object source) {super(source);}
}
package com.wy;
import java.util.EventListener;public interface KWICListener extends EventListener{public void handleEvent(KWICEvent event);
}
package com.wy;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;public class Outputer {public static void println(TextLines textlines) throws IOException {try (BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"))) {System.out.println("==== 输出开始 ====");for (int i = 0; i < textlines.numberOfLines(); i++) {String line = textlines.getLine(i);bw.write(line);bw.newLine();          // 写入文件System.out.println(line); // 同时打印到控制台}System.out.println("==== 输出完成 ====");}}
}
package com.wy;
import java.util.ArrayList;public class TextLine {private ArrayList<String> lines=null;public TextLine(){lines=new ArrayList<String>();}public String getLine(int index){return lines.get(index);}public ArrayList<String> getLineList(){return lines;}public void addLine(String line){lines.add(line);}public void addLine(int index,String line){lines.add(index,line);}public int numberOfLines(){return lines.size();}public int numberOfWords(int index){return lines.get(index).split(" ").length;}public  String  shiftwords(int line_index){String line=this.getLine(line_index);int temp_index=line.indexOf(' ');String temp1="";String temp2="";if(temp_index!=-1){temp1=line.substring(0,temp_index);temp2=line.substring(temp_index+1);lines.set(line_index,temp2+" "+temp1);return temp2+" "+temp1;}else return null;}
}
package com.wy;
import java.util.ArrayList;public class TextLines {private ArrayList<String> lines=null;public TextLines(){lines=new ArrayList<String>();}public String getLine(int index){return lines.get(index);}public ArrayList<String> getLineList(){return lines;}public void addLine(String line){lines.add(line);}public void addLine(int index,String line){lines.add(index,line);}public int numberOfLines(){return lines.size();}public int numberOfWords(int index){return lines.get(index).split(" ").length;}
}

⚖️ 隐式调用 vs 显式调用对比

对比项隐式调用(当前实现)显式调用(传统调用)
耦合度低,模块通过事件通信高,模块之间需直接引用调用
可扩展性高,新增功能只需注册监听器低,需修改原始模块
调试难度相对较高,需跟踪事件链路低,调用路径明确
控制流掌握不明显,控制权分散明确,调用顺序可控
适用场景GUI、分布式系统、日志系统等异步/解耦需求场景简单流程、数据依赖强的系统

🌟 总结

特点说明
松耦合各组件(如 InputerCircularShifterAlphabetizer)不直接依赖彼此,而是通过 EventManager 进行事件通信
事件驱动采用观察者模式,KWICListener 监听事件,KWICEvent 触发相应处理逻辑
职责分离每个模块专注于单一功能(如输入、移位、排序、输出),符合单一职责原则(SRP)
可扩展性新增处理逻辑只需注册新监听器,无需修改现有代码

KWIC 的隐式调用架构通过事件机制实现模块间通信,相比传统分层或管道-过滤器架构,具有更高的灵活性和可维护性。该设计模式适用于需要动态扩展、松耦合的场景,是事件驱动架构(EDA)的典型实践。


http://www.hkcw.cn/article/KMPCKVRHAc.shtml

相关文章

JWT 入门

一、JWT 概述 1. 扩展(Cookie、Session、Token) 灵魂拷问&#xff1a;为什么你的淘宝账号关闭后&#xff0c;购物车还在&#xff1f;其实这是Cookie 在搞事情。它就像是一种入场券&#xff0c;有该入场券就可以随意进出关卡。但这有个致命的弱点&#xff0c;Cookie是存在客户…

传统液晶瓶颈待破?铁电液晶如何实现显示技术逆袭

一、传统液晶显示&#xff1a;繁华背后的技术枷锁 在消费电子与专业显示领域&#xff0c;液晶技术&#xff08;LCD&#xff09;凭借成熟的产业链和性价比优势&#xff0c;长期占据主流地位。然而&#xff0c;随着 VR/AR、车载显示、高端投影等新兴场景的崛起&#xff0c;传统液…

Mybatis:灵活掌控SQL艺术

在前面的文章中&#xff0c;小编分享了spring中相关的知识&#xff0c;但是没有分享到&#xff0c;如何去更高效操作数据库。 操作数据库传统的方法就是通过JDBC来进行操作。 这个传统方法使用上可谓是够麻烦的 1.首先创建一个数据源对象 2.设置该数据源的属性&#xff08;…

STM32CubeMX定时器配置

STM32CubeMX定时器配置 一&#xff0c;Mode界面1&#xff0c;Slave Mode (从模式)2&#xff0c;Trigger Source (触发源) 三&#xff0c;Channelx&#xff08;通道模式&#xff09;1&#xff0c;Input Capture2&#xff0c;Output Compare3&#xff0c;PWM Generation4&#xf…

可灵2.1 vs Veo 3:AI视频生成谁更胜一筹?

在Google发布Veo 3几天后,可灵显然感受到了压力,发布了即将推出的视频模型系列可灵 2.1的早期体验版。 据我了解,有三种不同的模式: 可灵 2.1 标准模式: 720p分辨率 仅支持图像转视频(生成更快,一致性更好) 5秒视频仍需20积分 可灵 2.1 专业模式: 1080p分辨率 仅在图…

推荐几个不错的AI入门学习视频

引言&#xff1a;昨天推荐了几本AI入门书&#xff08;AI入门书&#xff09;&#xff0c;反响还不错。今天&#xff0c;我再推荐几个不错的AI学习视频&#xff0c;希望对大家有帮助。 网上关于AI的学习视频特别多。有收费的&#xff0c;也有免费的。我今天只推荐免费的。 我们按…

【机器学习】支持向量机

文章目录 一、支持向量机简述1.概念2.基本概念3.算法介绍4.线性可分5.算法流程 二、实验1.代码介绍2.模型流程3.实验结果4.实验小结 一、支持向量机简述 1.概念 支持向量机&#xff08;SVM&#xff09;是一类按监督学习方式对数据进行二元分类的广义线性分类器&#xff0c;其…

scale up 不能优化 TCP 聚合性能

scale up 作为一种系统扩展优化的方法&#xff0c;旨在提高系统组件的执行效率&#xff0c;比如替换更高性能的硬件或算法。是否可以此为依据优化 TCP 呢&#xff0c;例如通过多条路径聚合带宽实现吞吐优化(对&#xff0c;还是那个 MPTCP)&#xff0c;答案是否定的。 因为 TCP…

深度学习|pytorch基本运算-广播失效

【1】引言 前序文章中&#xff0c;已经学习了pytorch基本运算中的生成随机张量、生成多维张量&#xff0c;以及张量的变形、加减和广播运算。 今天的文章在之前学习的基础上&#xff0c;进一步探索。 前序文章链接为&#xff1a; 深度学习|pytorch基本运算-CSDN博客 【2】…

Asp.Net Core SignalR的分布式部署

文章目录 前言一、核心二、解决方案架构三、实现方案1.使用 Azure SignalR Service2.Redis Backplane(Redis 背板方案&#xff09;3.负载均衡配置粘性会话要求无粘性会话方案&#xff08;仅WebSockets&#xff09;完整部署示例&#xff08;Redis Docker&#xff09;性能优化技…

Linux环境搭建MCU开发环境

操作系统版本&#xff1a; ubuntu 22.04 文本编辑器&#xff1a; vscode 开发板&#xff1a; stm32f103c8t6 调试器&#xff1a; st-link 前言 步骤一&#xff1a; 安装交叉编译工具链 步骤二&#xff1a; 创建工程目录结构 步骤三&#xff1a; 调试…

VR/AR 视网膜级显示破局:10000PPI 如何终结颗粒感时代?

一、传统液晶 “纱窗效应”&#xff1a;VR 沉浸体验的最大绊脚石 当用户首次戴上 VR 头显时&#xff0c;眼前密密麻麻的像素网格往往打破沉浸感 —— 这正是传统液晶显示在近眼场景下的致命缺陷。受限于 500-600PPI 的像素密度&#xff0c;即使达到 4K 分辨率&#xff0c;等效到…

【教学类-36-10】20250531蝴蝶图案描边,最适合大小(一页1图1图、2图图案不同、2图图案相同对称)

背景说明: 之前做了动物头像扇子(描边20),并制作成一页一套图案对称两张 【教学类-36-09】20250526动物头像扇子的描边(通义万相)对称图40张,根据图片长宽,自动旋转图片,最大化图片-CSDN博客文章浏览阅读1k次,点赞37次,收藏6次。【教学类-36-09】20250526动物头像…

灌水论坛系统总体设计文档

一、实验题目 灌水论坛系统 二、实验目的 旨在通过一个相对完整且功能丰富的Web应用实例&#xff0c;全面地实践和巩固Web开发所需的各项核心技术和工程方法&#xff0c;从而提升其综合应用能力和解决实际开发问题的能力。它不仅仅是完成一个软件&#xff0c;更是一个学习、…

TK海外抢单源码/指定卡单

​ 抢单源码&#xff0c;有指定派单&#xff0c;打针&#xff0c;这套二改过充值跳转客服 前端vue 后端php 两端分离 可二开 可以指定卡第几单&#xff0c;金额多少&#xff0c; 前后端开源 PHP7.2 MySQL5.6 前端要www.域名&#xff0c;后端要admin.域名 前端直接静态 伪静…

印军高官为何指责83架光辉订单0交付 国产战机交付延迟

印度空军参谋长辛格在印度工业联合会举办的年度商业峰会上严厉批评本国的航空制造业,指出印度大型国防项目的落实没有如期进行,包括国产“光辉”战机在内的战斗机向空军交付均出现延迟。根据2021年与印度斯坦航空有限公司签订的价值4800亿卢比(约合404亿元人民币)的合同,印…

年轻人开始主动挂艾草了 老习俗焕发新活力

今年端午节当天,“年轻人开始主动挂艾草了”登上小红书APP热点榜首,截至晚上9点30分浏览量达到918万次。菜市场几块钱一把的野生艾草,在年轻人手中经过巧手改造,搭配菖蒲叶、玉簪叶、香樟果和铃铛,变成了身价百元的“祈福门挂”。如今,挂艾草不再只是简单的节庆习俗,而是…

Roguelike地牢:混沌系统与涌现式玩法设计

目录 Roguelike地牢:混沌系统与涌现式玩法设计引言第一章 地牢生成算法1.1 多级生成策略1.2 柏林噪声应用第二章 道具生态系统2.1 属性耦合模型2.2 道具稀有度系统第三章 敌人行为树3.1 自适应难度3.2 状态机设计第四章 永久死亡机制4.1 元进度系统4.2 遗产继承设计第五章 光照…

【数据集】基于累计分布函数匹配CDF Matching与多分辨率卡尔曼滤波MKF相结合的地表温度(2002-2020)

目录 数据概述一、输入数据二、生产流程与处理方法步骤一:生成被动微波LST数据(PMW LST)步骤二:CDF匹配提高高分辨率LST质量步骤三:多分辨率卡尔曼滤波(MKF)融合生成全时空覆盖LST三、模拟效果与实验结果四、生成空间完整全天候LST五、验证与精度评估数据下载下载方式1:…

探索Python中的Dask:高效处理大规模数据的利器

在当今数据驱动的时代&#xff0c;处理大规模数据集已成为许多领域的重要挑战。Python作为数据科学和机器学习领域的主流编程语言&#xff0c;虽然拥有NumPy和Pandas等强大的库&#xff0c;但在面对超出内存限制的大数据集时&#xff0c;这些工具往往显得力不从心。Dask作为一款…