外观设计模式(Facade):跨子系统传递MyClass类型的正确方式
子系统外观模式下的类型传递与解耦方案
是否应通过外观传递MyClass类型?
绝对不应该。直接传递子系统A的内部类MyClass会让子系统B依然强依赖A的实现细节,耦合度问题根本没解决——外观模式的核心价值就是隐藏子系统内部结构,降低外部依赖,传递内部类型完全违背了这个初衷。
正确的实现方式
根据MyClass的定位(纯数据载体/带业务行为)和子系统B的需求,有三种典型的解耦方案:
1. 定义独立数据传输对象(DTO)
如果MyClass只是纯数据载体,在外观层或独立的公共模块中定义与MyClass数据结构一致的DTO(比如MyClassDTO),由外观负责MyClass与DTO之间的转换,子系统B的方法参数换成DTO类型。
示例代码:
// 子系统A内部类(无需修改) public class MyClass { private String name; private int age; // Getter/Setter } // 公共DTO(放在外观模块或公共包) public class MyClassDTO { private String name; private int age; // Getter/Setter } // 子系统A的外观类 public class SubsystemAFacade { public MyClass createMyClass(String name, int age) { return new MyClass(name, age); } public MyClassDTO convertToDTO(MyClass myClass) { MyClassDTO dto = new MyClassDTO(); dto.setName(myClass.getName()); dto.setAge(myClass.getAge()); return dto; } } // 子系统B的方法(修改为依赖DTO) public class SubsystemB { public void processData(MyClassDTO dto) { System.out.println("处理数据:" + dto.getName() + ",年龄:" + dto.getAge()); } } // 客户端调用 public class Client { public static void main(String[] args) { SubsystemAFacade facade = new SubsystemAFacade(); MyClass myClass = facade.createMyClass("张三", 25); MyClassDTO dto = facade.convertToDTO(myClass); SubsystemB subsystemB = new SubsystemB(); subsystemB.processData(dto); } }
2. 抽象公共接口
如果MyClass包含业务行为,在公共模块定义抽象接口(比如IMyClass),让MyClass实现该接口,外观层返回接口类型,子系统B的方法参数使用接口而非具体类。
示例代码:
// 公共接口 public interface IMyClass { String getName(); int getAge(); void doBusiness(); } // 子系统A内部类实现接口 public class MyClass implements IMyClass { private String name; private int age; @Override public String getName() { return name; } @Override public int getAge() { return age; } @Override public void doBusiness() { // 子系统A内部业务逻辑 System.out.println("执行A内部业务"); } } // 子系统A的外观类 public class SubsystemAFacade { public IMyClass createMyClass(String name, int age) { return new MyClass(name, age); } } // 子系统B的方法(依赖抽象接口) public class SubsystemB { public void triggerBusiness(IMyClass myClass) { myClass.doBusiness(); System.out.println("基于数据:" + myClass.getName() + "处理B逻辑"); } }
3. 完全封装业务逻辑
如果子系统B不需要直接操作MyClass的任何数据或行为,只是触发子系统A的某个业务流程,直接将该业务封装到外观方法中,子系统B仅调用外观方法,无需接触任何A的内部类型。
示例代码:
// 子系统A内部类 public class MyClass { private String name; private int age; public void executeInternalLogic() { // 子系统A内部业务逻辑 System.out.println("执行A内部逻辑:" + name); } } // 子系统A的外观类 public class SubsystemAFacade { public void runBusiness(String name, int age) { MyClass myClass = new MyClass(name, age); myClass.executeInternalLogic(); // 其他A内部流程 } } // 子系统B的方法(直接调用外观) public class SubsystemB { public void startProcess() { SubsystemAFacade facade = new SubsystemAFacade(); facade.runBusiness("张三", 25); } }
核心原则
无论哪种方案,核心都是让子系统B与子系统A的内部实现完全隔离:B只依赖公共的DTO、抽象接口或外观提供的方法,不直接引用A的任何内部类,这样才能真正降低耦合度,符合外观模式的设计目标。
内容的提问来源于stack exchange,提问作者Gilded Json
相关产品推荐
相关产品推荐

