本文介绍了代理模式与覆盖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设有一个接口Subject。

  interface Subject {void request(); } 

我们有一个RealSubject类。假设我们要增强RealSubject,我们可以使用包裹RealSubject的Proxy模式:

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

或者我们可以扩展RealSubject并覆盖方法

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

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



如果没有接口Subject(即RealSubject不实现任何接口),似乎继承和覆盖是唯一的选项因为在代理模式中没有实现接口。如果没有主题界面,你还可以应用代理模式吗?

解决方案

为了回应你的第一个问题,方法更好



我个人更喜欢使用Interface和Proxy(或Decorator)模式来实现这样的功能。 (见:项目16:对)



如果超类( RealSubject )不在您的控制之内,即在同一个包中,专门为扩展设计和记录,从版本到版本的任何更改都可能会破坏子类的实现( EnhancedSubject )。基本上我在说的是:根据具体实现,导致脆弱的代码。



为了回应您的第二个问题,如果 EnhancedSubject 满足Liskov原则,你还会考虑继承?



再次如果 RealSubject 和 EnhancedSubject 在您的控制之下并以相同的生命周期发布,那么可以安全地使用继承,但是



另一点希望您使用界面实现的方法是Unit
测试。



例如,使用您想要应用单元测试的情况,注入的模拟依赖将会更容易将代理的RealSubject 实现实现主题,以便您可以专门测试代理类,而不是必须完全测试整个对象层次结构, RealSubject 和 EnhancedSubject ,只是为了确认 EnhancedSubject 的行为与预期的一样。



我想可以这么说,如果这是一个非常简单的API,它几乎不会改变未来,具体实现简单简单。并保持简单愚蠢(KISS)是最好的政策之一。



如果没有主题界面,您仍然可以应用代理模式吗?
您可以将 RealSubject 注入另一个类,并在内部使用 RealSubject ,但如果API使用 RealSubject 直接依赖于具体的类,你没有别的选择,而是使用继承。


Suppose there is a interface Subject.

interface Subject { void request(); }

We have a RealSubject class. Suppose we want to enhance RealSubject, we can either use Proxy pattern that wraps around a RealSubject:

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

or we can extends RealSubject and override the method

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

Which approach is better? I'm aware of Liskov principle; let's suppose that EnhancedSubject satisfies the Liskov principle. Do you still consider inheritance?

If there is no interface Subject (i.e., RealSubject doesn't implement any interface), it seems "inherit and override" is the only option as there is no interface to implement in Proxy pattern. Can you still apply Proxy pattern if there is no Subject interface?

解决方案

In response to your first question, "which approach is better"?

I'd personally prefer using the Interface and Proxy (or Decorator) pattern to implement something like this. (See: Item 16: Favor composition over inheritance of Effective Java (2nd Edition))

If the superclass (RealSubject) is not under your control, i.e. in the same package, and specifically designed and documented for Extension, any changes to it's implementation from version to version may break your implementation of the subclass (EnhancedSubject). Essentially what I'm saying is: Depending directly on a concrete implementation leads to fragile code.

In response to your second question, "If EnhancedSubject satisfies the Liskov principle, Do you still consider Inheritance?"

Once again it is safe to use inheritance if the RealSubject and EnhancedSubject are under your control and released with the same life cycle, but Depending directly on a concrete implementation leads to fragile code.

Another point that hopefully sways you towards using the Interface implemenation is Unit Testing.

For Example, Using the case that you would want to apply Unit Testing, it would be a lot easier to inject a mock dependency of RealSubject into your Proxy implementation of Subject so that you can specifically test the Proxy class, rather than have to completely test the whole object hierarchy, RealSubject and EnhancedSubject, just to confirm that EnhancedSubject behaves as expected.

I suppose it can be said though, that if it's all a very simple API and it will not change hardly at in future, Concrete implementations are simply simpler. And Keep It Simple Stupid (K.I.S.S.) is one of the best policies.

"Can you still apply Proxy pattern if there is no Subject interface?"You could inject RealSubject into another class and use RealSubject internally, but if the API using RealSubject depends directly on the concrete class, you have no other choice, but to use Inheritance.

这篇关于代理模式与覆盖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 03:24