基于函数式接口的Access object实现:类A、B、C交互问题咨询
解决方案:通过函数式接口解耦B与C,同时保证封装性
这是个典型的组件解耦场景,用函数式接口刚好能优雅满足你的要求,我给你一步步拆解实现方案:
1. 定义公共函数式接口
先创建一个仅含单个抽象方法的函数式接口,作为“追加文本”的行为契约:
@FunctionalInterface public interface TextAppendable { /** * 向目标组件追加文本 * @param text 需要追加的内容 */ void appendText(String text); }
标注@FunctionalInterface是为了明确这是函数式接口,编译器会自动校验它只有一个抽象方法。
2. 让B实现该函数式接口
B内部持有TextArea,通过实现TextAppendable接口的appendText方法来操作自身的TextArea——既满足“B实现公共函数式接口”的要求,又不用暴露内部的TextArea,完美保证封装性:
import javafx.scene.control.TextArea; // 以JavaFX为例,Swing替换为JTextArea即可 import javafx.application.Platform; public class B implements TextAppendable { private final TextArea textArea; public B() { this.textArea = new TextArea(); // 可在此初始化TextArea的样式、大小等属性 } @Override public void appendText(String text) { // 注意:UI组件操作必须在对应UI线程执行,这里以JavaFX为例 Platform.runLater(() -> textArea.appendText(text + "\n")); // Swing环境替换为:SwingUtilities.invokeLater(() -> textArea.append(text + "\n")); } // B的其他业务方法... }
3. 让C依赖函数式接口而非具体类
C不需要知道B的存在,只需要依赖TextAppendable接口来传递生成的文本。我们通过构造器注入的方式把接口实例传给C,彻底解耦C和具体实现类:
public class C { private final TextAppendable textAppendable; // 构造器注入接口实例,C只关心"追加文本"的行为,不关心是谁实现的 public C(TextAppendable textAppendable) { this.textAppendable = textAppendable; } // C生成文本的业务方法示例 public void generateAndAppendText() { // 模拟文本生成逻辑 String generatedContent = String.format("C生成的文本:%s", System.currentTimeMillis()); // 通过接口把文本传递给B textAppendable.appendText(generatedContent); } // C的其他业务方法... }
4. 让A作为协调者关联B和C
A作为上级类,持有B和C的实例,负责把B(作为TextAppendable接口实例)传递给C,完成组件间的关联:
public class A { private final B bInstance; private final C cInstance; public A() { this.bInstance = new B(); // 把B的实例传给C,因为B实现了TextAppendable接口 this.cInstance = new C(bInstance); } // 触发文本生成的示例方法 public void startTextGeneration() { // 模拟后台生成文本的场景 new Thread(() -> { for (int i = 0; i < 5; i++) { cInstance.generateAndAppendText(); try { Thread.sleep(1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } }).start(); } // A的其他业务方法... }
方案优势说明
- 彻底解耦B与C:两者之间没有直接引用,完全通过抽象接口通信,符合依赖倒置原则,后续修改其中一个组件不会影响另一个。
- 严格保证封装性:B不需要暴露内部的TextArea,只通过接口提供必要的功能,避免外部直接操作内部组件带来的风险。
- 满足函数式接口要求:B实现了公共函数式接口,同时接口的设计也让代码更灵活——如果需要临时替换文本接收方,甚至可以用lambda表达式直接创建接口实例,无需额外编写类。
内容的提问来源于stack exchange,提问作者PeterPan
相关产品推荐
相关产品推荐

