代理模式与重写模式

2023-12-19

假设有一个接口Subject。

interface Subject { void request(); }

我们有一个 RealSubject 类。假设我们想要增强 RealSubject,我们可以使用包装 RealSubject 的代理模式:

class Proxy implements Subject { 
   private RealSubject ref;
   void request(){ ... }
}

或者我们可以扩展 RealSubject 并重写该方法

class EnhancedSubject extends RealSubject {
   @Override
   void request() { ... }
}

哪种方法更好?我知道里氏法则;我们假设EnhancedSubject满足Liskov原则。还考虑继承吗?

如果没有Subject接口(即RealSubject没有实现任何接口),似乎“继承并覆盖”是唯一的选择,因为在代理模式中没有可以实现的接口。如果没有Subject接口还可以应用Proxy模式吗?


回答你的第一个问题,“哪种方法更好"?

我个人更喜欢使用接口和代理(或装饰器)模式来实现这样的东西。 (参见:第 16 条:优先考虑组合而不是继承有效的Java(第二版) http://java.sun.com/docs/books/effective/toc.html)

如果超类(RealSubject)不在您的控制之下,即在同一个包中,并且专门为扩展设计和记录,版本之间对其实现的任何更改都可能会破坏子类的实现(EnhancedSubject)。本质上我想说的是:直接依赖于具体的实现会导致代码脆弱。

针对你的第二个问题,“If EnhancedSubject满足里氏原理,还考虑继承吗?"

再次强调,如果满足以下条件,那么使用继承是安全的:RealSubject and EnhancedSubject都在你的控制之下,并以相同的生命周期发布,但是直接依赖于具体的实现会导致代码脆弱。

希望促使您使用 Interface 实现的另一点是 Unit 测试。

例如,使用您想要应用单元测试的情况,注入模拟依赖项会容易得多RealSubject进入你的Proxy实施Subject这样你就可以专门测试Proxy类,而不是必须完全测试整个对象层次结构,RealSubject and EnhancedSubject,只是为了确认EnhancedSubject行为符合预期。

我想可以说,如果它都是一个非常简单的 API 并且将来几乎不会改变,那么具体的实现就很简单了simpler。保持简单愚蠢(K.I.S.S.)是最好的政策之一。

"如果没有Subject接口还可以应用Proxy模式吗?” 你可以注射RealSubject进入另一个类并使用RealSubject内部,但如果 API 使用RealSubject直接依赖于具体的类,你别无选择,只能使用继承。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

代理模式与重写模式 的相关文章

随机推荐