KWIC—Implicit Invocation

news2025/6/3 9:07:48

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;
    @Override
    public 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;
    @Override
    public 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.coloradmin.cn/o/2394710.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Visual Studio 2022 发布独立的 exe 文件

我们在用 Visual Studio 2022 写好一个 exe 程序之后&#xff0c;如果想把这个拿到其他地方运行&#xff0c;需要把 exe 所在的文件夹一起拿过去。 编译出来的 exe 文件需要其他几个文件一同放在同一目录才能运行&#xff0c;原因在于默认情况下&#xff0c;Visual Studio 是把…

11.4java语言执行浅析4

编译成字节码&#xff08;.class 文件&#xff09; 使用 javac 命令将源代码编译为 Java 字节码&#xff08;bytecode&#xff09; 它不是机器码&#xff0c;而是 JVM 能理解的中间语言&#xff08;字节码&#xff09;&#xff0c;具有平台无关性。 编译过程简要&#xff1…

python分配方案数 2023年信息素养大赛复赛/决赛真题 小学组/初中组 python编程挑战赛 真题详细解析

python分配方案数 2023全国青少年信息素养大赛Python编程挑战赛复赛真题解析 博主推荐 所有考级比赛学习相关资料合集【推荐收藏】1、Python比赛 信息素养大赛Python编程挑战赛 蓝桥杯python选拔赛真题详解

《信号与系统》第 5 章 离散时间傅里叶变换

5.0 引言 这一章将介绍并研究离散时间傅里叶变换&#xff0c;这样就完整地建立了傅里叶分析方法。 5.1 非周期信号的表示&#xff1a;离散时间傅里叶变换 5.1.1 离散时间傅里叶变换的导出 在第4章看到&#xff1a;一个连续时间周期方波的傅里叶级数可以看成一个包络函数的采…

动态IP与区块链:重构网络信任的底层革命

在数字经济蓬勃发展的今天&#xff0c;网络安全与数据隐私正面临前所未有的挑战。动态IP技术与区块链的深度融合&#xff0c;正在构建一个去中心化、高可信的网络基础设施&#xff0c;为Web3.0时代的到来奠定基础。 一、技术碰撞&#xff1a;动态IP与区块链的天然契合 动态I…

uniapp使用Canvas生成电子名片

uniapp使用Canvas生成电子名片 工作中有生成电子名片的一个需求&#xff0c;刚刚好弄了发一下分享分享 文章目录 uniapp使用Canvas生成电子名片前言一、上代码&#xff1f;总结 前言 先看效果 一、上代码&#xff1f; 不对不对应该是上才艺&#xff0c;哈哈哈 <template…

世冠科技亮相中汽中心科技周MBDE会议,共探汽车研发数字化转型新路径

近日&#xff0c;中汽中心2025年科技周MBDE前沿应用主题会议在天津成功举办。本次会议以“智汇津门共探MBDE前沿应用新征程”为主题&#xff0c;聚焦基于模型的数字工程&#xff08;MBDE&#xff09;方法论在汽车复杂系统研发中的创新实践与跨领域协同&#xff0c;旨在推动行业…

Linux笔记---线程

1. 线程的介绍 1.1 线程的概念 基本定义&#xff1a; 线程&#xff08;Thread&#xff09;是操作系统能够进行运算调度的最小单位。它被包含在进程&#xff08;Process&#xff09;之中&#xff08;或者说是进程的一部分、对进程的划分&#xff09;&#xff0c;是进程中的实际…

MCP架构深度解析:从基础原理到核心设计

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 持续学习&#xff0c;不断…

数据库暴露--Get型注入攻击

1.背景知识 1.1Post、Get的对比 特性GET 方法POST 方法HTTP 方法类型GETPOST数据位置URL 查询字符串(?key=value)请求体(Request Body)数据可见性明文显示在 URL 和浏览器历史中不可见(除非开发者工具查看)数据长度限制受 URL 长度限制(通常约 2048 字符)无明确限制(…

AI炼丹日志-26 - crawl4ai 专为 AI 打造的爬虫爬取库 上手指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; Java篇&#xff1a; MyBatis 更新完毕目前开始更新 Spring&#xff0c;一起深入浅出&#xff01; 大数据篇 300&#xff1a; Hadoop&…

ESP32-idf学习(四)esp32C3驱动lcd

一、前言 屏幕是人机交互的重要媒介&#xff0c;而且现在我们产品升级的趋势越来越高大尚&#xff0c;不少产品都会用lcd来做界面&#xff0c;而esp32c3在一些项目上是可以替代主mcu&#xff0c;所以驱动lcd也是必须学会的啦 我新买的这块st7789&#xff0c;突然发现是带触摸…

【python】uv管理器

uv是一个速度极快的 Python 包和项目管理器&#xff0c;用 Rust 编写。 安装 安装uv之前&#xff0c;确保你的电脑不需要安装了python 在Windows下&#xff0c;可以使用官方的脚本直接安装 powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.…

戴尔AI服务器订单激增至121亿美元,但传统业务承压

戴尔科技121亿美元的AI服务器订单&#xff0c;不仅超过了公司整个2025财年的AI服务器出货量&#xff0c;更让其AI订单积压达到144亿美元的历史高位。 戴尔科技最新财报显示&#xff0c;AI服务器需求的爆炸式增长正在重塑这家老牌PC制造商的业务格局&#xff0c;但同时也暴露出…

如何手搓扫雷(待扩展)

文章目录 一、扫雷游戏分析与设计1.1 扫雷游戏的功能说明1.2 游戏的分析和设计1.2.1 数据结构的分析1.2.2 文件结构设计 二、扫雷游戏的代码实现三、扫雷游戏的扩展总结 一、扫雷游戏分析与设计 扫雷游戏网页版 1.1 扫雷游戏的功能说明 使用控制台&#xff08;黑框框的程序&a…

俄军操作系统 Astra Linux 安装教程

安装 U盘制作 Rufus 写盘工具&#xff1a;https://rufus.ie/ Astra Linux ISO 镜像文件&#xff1a;https://dl.astralinux.ru/astra/stable/2.12_x86-64/iso/ 准备一个8g以上的u盘&#xff0c;打开Rufus写盘工具&#xff0c;选择下载的iso镜像&#xff0c;写入u盘&#xff…

第三方软件评测机构如何助力软件品质提升及企业发展?

第三方软件评测机构与软件开发者及使用者无直接关联&#xff0c;它们提供全方位的检测和公正的评价服务。这样的评测可以展现客观的成效&#xff0c;对提升软件的品质具有显著影响&#xff0c;且在软件产业中发挥着至关重要的角色。 评测的客观性 独立第三方机构与软件开发者…

Python打卡训练营Day40

DAY 40 训练和测试的规范写法 知识点回顾&#xff1a; 彩色和灰度图片测试和训练的规范写法&#xff1a;封装在函数中展平操作&#xff1a;除第一个维度batchsize外全部展平dropout操作&#xff1a;训练阶段随机丢弃神经元&#xff0c;测试阶段eval模式关闭dropout 作业&#x…

JS逆向案例—喜马拉雅xm-sign详情页爬取

JS逆向案例——喜马拉雅xm-sign详情页爬取 声明网站流程分析总结 声明 本文章中所有内容仅供学习交流&#xff0c;抓包内容、敏感网址、数据接口均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff0c;若有侵权&am…

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…