关于装饰器和策略模式 C# 的 OOP 设计问题
举例来说,你有一个基础抽象类
public abstract Foo
{
IFlyable _fly;
ISwimmable _swim;
void performSwim()
{
_swim.swim();
}
void performFly()
{
_fly.fly();
}
}
,并且有你的系统中将有的行为/算法
interface IFlyable { void fly(); }
interface ISwimmable { void swim(); }
interface IVoteable { void vote(); }
等等
现在你有多个类来实现它,具体为 IFlyable、ISwimmable 等等
class Bar: Foo { _swim = new ConcerteSwim(); }
class Baz: Foo { _fly = new ConcreteFly(); }
等,
其中之一是在基础中使用策略模式Foo 类来交换行为。
我们还可以使用装饰器模式来用某些行为来包装它,但是由于装饰器用基类来包装它,如果我们稍后向对象添加更多行为,我们如何真正允许开闭原则在不触及基类的情况下工作。 由于当我们添加更多行为时,这些行为可能会有不同的签名,而不仅仅是像调用装饰器那样,
void performSwim()
{
swimWithMoreSpeed() + foo.performSwim()
}
我想我的问题是,如果我添加更多行为,我如何才能在不修改基类的情况下仍然能够说添加 IWeaponBehavior、ISomeBehaviour到一个班级。
例如我想要一个类
public class XYF: Foo
{
}
,但我想给它一些 ISomeBehaviour 的行为,有没有一种方法可以用这些行为来包装它,或者更像是一个 ConcreteFoo 用这些行为来包装它,现在做一些事情而不是在具体的 xyz 上实现接口,尽管这会让您实现多种具体行为类,例如 SwimBehaviour、NullBehaviour 等,但没有办法摆脱它。
有没有办法在设计模式中做到这一点? 它几乎看起来像是模式的混合体。
我知道,如果它像鸭子一样行走,像鸭子一样嘎嘎叫,但需要电池,那么你的抽象就有问题了。
希望这是有道理的。
Say for example you have a base abstract class
public abstract Foo
{
IFlyable _fly;
ISwimmable _swim;
void performSwim()
{
_swim.swim();
}
void performFly()
{
_fly.fly();
}
}
And have behaviors/algorithm that you will have in your system
interface IFlyable { void fly(); }
interface ISwimmable { void swim(); }
interface IVoteable { void vote(); }
etc etc
Now you have multiple class that implement it, with concrete of IFlyable, ISwimmable etc
class Bar: Foo { _swim = new ConcerteSwim(); }
class Baz: Foo { _fly = new ConcreteFly(); }
etc etc
One is using the strategy pattern in the base class of Foo to swap in the behaviours.
We could also use the decorator pattern to wrap it with certain behavior but since the decorator wraps it with base class, how do we actually allow the open close principle to work without touching the base class if we later on add more behaviors to objects. Since these behavior might have different signatures as we add more, rather than just for example like calling in decorator
void performSwim()
{
swimWithMoreSpeed() + foo.performSwim()
}
I guess my question is if I add more behavior, how can I not modify the base class and still be able to say add IWeaponBehavior, ISomeBehaviour to a class.
for example I want to have a class
public class XYF: Foo
{
}
But I want to give it some behavior of ISomeBehaviour, is there a way I could say wrap it with these kinds of behaviour, or more like here is an ConcreteFoo wrap it with these behaviours and now do stuff rather than implementing the interface on concrete xyz although that makes you implementing so many kinds of concretebehaviour class like swimbehaviour, nullbehaviour etc but there is no way out of it.
Is there a way to do this in design patterns? It almost seems like a hybrid of patterns.
I know it almost seems like if it walks like a duck and quacks like a duck but requires battery then you have something wrong with abstraction.
Hope this make sense.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
尝试装饰器模式。 要支持新行为,您只需实现一个继承自
Foo
的新类,实现IWeaponBehavior
并装饰另一个Foo
对象。 然后,您现在可以将WeaponDecorator
用作Foo
或IWeaponBehavior
,并且仍然可以访问它的基本Foo
装饰。基类:
具有基本行为的具体子类:
行为接口:
具有行为的装饰器子类:
现在我们可以使用其特定的
Jump()
实现来使任何Foo
飞行:Try the decorator pattern. To support a new behavior, you would just implement a new class that inherits from
Foo
, implementsIWeaponBehavior
, and decorates anotherFoo
object. Then you can now use theWeaponDecorator
as aFoo
orIWeaponBehavior
and still have access to the baseFoo
that it decorates.Base class:
Concrete subclasses with base behavior:
Behavior interfaces:
Decorator subclasses with behavior:
Now we can make any
Foo
fly, using its particular implementation ofJump()
:访客模式怎么样? 它允许基类的实现者改变行为,而无需强制基类针对每个新实现进行更改:
How about the visitor pattern? It allows implementors of your base class to vary behaviours without forcing the base class to change for each new implementation:
所以这是我对此的看法:
然后让 ISwimmable 等接口继承自 IBehavior。
So here's my take on this:
and then have your interfaces like ISwimmable, etc inherit from IBehavior.