【发布时间】:2020-06-16 22:24:59
【问题描述】:
我已经阅读了很多关于组合的内容,并试图弄清楚如何使用组合重构我的继承树。目前我的班级是这样的:
public abstract class BaseClass
{
public abstract string displayText { get; }
public abstract List<Parameter> parameters { get; }
public abstract void FireEvent();
}
public abstract class SubClass<T> : BaseClass
{
private string _displayText;
public override string displayText { get { return _displayText; } }
private List<Parameter> _parameters;
public override List<Parameter> parameters { get { return _parameters; } }
private T _value; // ADDED TO SUBCLASS
public abstract Event<T> Evt { get; } // ADDED TO SUBCLASS
public override void FireEvent()
{
Evt.Raise(_value);
}
}
public class IntClass : SubClass<int>{}
public class StringClass : SubClass<string>{} // more subclasses like this
据我了解,这里既有继承又有组合。
子类Has-A:(组成)
-
Parameters列表 -
Event的字段 -
Event<T>的行为在它自己的FireEvent方法中调用
子类Is-A:基类(继承)
IntClass/StringClass Is-A:子类和基类
创建BaseClass 的原因是因为我需要多态列表。这样我可以创建一个List<BaseClass> 并在列表中的每个元素上调用FireEvent() 并在循环中访问displayText 和List<Parameter>。
将来我需要一个没有Event 的子类和一个接受FireEvent() 参数的子类。可能会出现其他变体。
如何用基于组合的方法完全替换我当前的结构?它甚至可行吗?
【问题讨论】:
-
您为什么要这样做?所以你不会破坏 Liskov?
-
这不是更适合codereview.stackexchange.com吗?
-
如果你继承了一个类,那么它就是继承,当你将不同的类存储为字段或属性时,它就是组合。您应该根据自己的用例使用其中一个或两个,而不是一个接一个。
-
你看不到组合的好处。因为您只有 1 个行为(FireEvent())。假设你在 BaseClass 中有 5 个方法,在 SubClass 中有 10 个方法。然后你的 IntCass 和 StringClass 从上面继承了 15 个方法,但是 IntClass 只使用了 7 个,而 StringClass 只使用了 2 个。现在想象一下在你的 BaseClass 中更改 1 个方法,你不知道你是否有任何东西。这就是你想把你的 15 种方法放入服务的地方(可以是 1 个服务或多个服务)
-
@Alex-TinLe 是的,这正是我所关心的。我将在未来添加新的行为。我只是不确定如何为未来的灵活性重构它。您能否详细说明服务以及它的外观?
标签: c# oop generics inheritance composition