当前位置: 首页 > web >正文

KWIC—Implicit Invocation

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.xdnf.cn/news/10246.html

相关文章:

  • Redis实战-基于redis和lua脚本实现分布式锁以及Redission源码解析【万字长文】
  • 【android bluetooth 案例分析 04】【Carplay 详解 2】【Carplay 连接之手机主动连车机】
  • 【android bluetooth 案例分析 04】【Carplay 详解 3】【Carplay 连接之车机主动连手机】
  • K 值选对,准确率翻倍:KNN 算法调参的黄金法则
  • 当前用户的Git本地配置情况:git config --local --list
  • Python Day38 学习
  • 2025山东CCPC题解
  • Fragment事务commit与commitNow区别
  • 使用HTTPS进行传输加密
  • 每日Prompt:隐形人
  • Vue 核心技术与实战day07
  • Java多线程并发常见问题与解决方案
  • vue2源码解析——响应式原理
  • Linux【工具 04】Java等常用工具的多版本管理工具SDKMAN安装使用实例
  • 华为OD机试真题—— 最少数量线段覆盖/多线段数据压缩(2025A卷:100分)Java/python/JavaScript/C++/C语言/GO六种最佳实现
  • 【算法】动态规划
  • 【Dv3Admin】工具分页配置文件解析
  • 姜老师的MBTI课程:MBTI是可以转变的
  • Java代码重构:如何提升项目的可维护性和扩展性?
  • Linux.docker.k8s基础概念
  • 【设计模式-4.5】行为型——迭代器模式
  • 自定义载板RK3588HDMI输入配置完整解决方案
  • Catch That Cow POJ - 3278
  • fdw批量导入外部表
  • 7.CircuitBreaker断路器
  • 【js逆向】某某省过验证码逆向
  • hantools 常用函数
  • 第二代IndoorLink头戴式无线讲解器,远距+动感,更好用了
  • 数据交易场景的数据质量评估
  • 权限分配不合理如何影响企业运营?