从图片中,我可以使用继承而不是实现接口吗?
我的意思是从“ConcreteStrategyA
和ConcreteStrategyB
实施Strategy
接口”更改为“ConcreteStrategyA
和ConcreteStrategyB
扩展Strategy
类”
它仍然运作良好或有问题吗?
如果它仍然有效,我的下一个问题是“为什么大多数人更喜欢使用界面?”
答案 0 :(得分:3)
从技术上来说,从具有策略模式的设计模式角度来看,具体的策略需要实现(我的意思是编写代码,而不是接口实现的东西)是策略上下文所知道的常见契约。这是战略模式哲学的主要支柱。遵守通用契约是允许策略上下文基于某些运行时特征替换具体策略的原因。这种模式意识形态就是我们在OOP用语中所谓的多态性。 现在在Java中,您可以将其多态策略实现为接口或继承。对于接口,您已在问题本身中给出了示例。对于继承,只要契约在子类之间成立(类似于具有抽象契约的基本抽象类,子类实现以提供具体的策略实现),您也可以在继承中实现策略模式。
现在从OOP的角度思考它。对于OOP继承,子类继承自超类。子类自动拥有并因此演示了继承的通用行为,但它可以选择使该行为更加特定于其自己的类型。因此,多个子类可以覆盖相同的行为,并使其位更具体。但是当这个链变得太长或者子类试图继承逻辑上不适用于它们的行为时,这个链变得很麻烦。
因此,使用接口实现策略模式比继承更有意义。
答案 1 :(得分:2)
绝对。当您希望派生策略共享一些公共代码时,继承最常用于抽象基类。
人们更喜欢在具体的基类上使用接口或抽象类,因为:
使用依赖性倒置方法,类需要与其策略松散耦合。它只需要知道战略履行合同,但不想知道其实施细节。接口和抽象类是定义合同而不指定实现的优雅且最小的方式。
在大多数情况下实例化基本策略类是没有意义的,因为它是一个通用的抽象概念 - 实际上,如果你禁止实例化它会更好。
答案 2 :(得分:0)
没有技术问题。
但是,类只能扩展一个基类,但它可以实现多个接口。因此,如果您愿意,让我们说,将来更改您的继承结构,如果您选择实现接口,则会更容易。
答案 3 :(得分:0)
如您所知,设计模式是“常见问题的一般解决方案”。它只是描述了一个一般解决方案,没有关于实现细节的指示。
如果您的问题需要一个类来代替接口,那么将它替换为具体(或抽象)类没有任何错误。
在UML模式中使用界面是一种说法:“你必须暴露这组公共方法”。
所以,使用你的方法没问题。作为替代方案,您可以离开Strategy
界面并在StrategyImpl
课程中实施该界面,然后您可以在ConcreteStrategyA
和ConcreteStrategyB
课程中继承此课程。