不要重复自己 要么 封装
我们说我创建了以下内容:
我想让Marker实现IMask接口。但后来我要重复自己(最后检查代码) 或者我可以在Marker公众中找到我的位置。但接下来我会暴露我班级的实施。 或者我可以从Spot继承Spot,但这不是理想的解决方案,因为语义上Marker不是特定类型的Spot。
如果我创建另一个将Spot作为字段并且我又想要实现IMask接口的类呢? 我会再次重复自己。 那么,我该怎么办?我应该在Spot中公开列表吗?然后将Spot in Marker公之于众? 或者我应该重复这些电话吗?
interface IMask : IList<Point>
{
public void MoveTo(Point newCenter);
// ... other Methods
}
public class Spot : IMask
{
List<Point> points;
public void DoSpotyStuff()
{
// blabla
}
// Other methods
// ...
// Finally the implementation of IMask
public void MoveTo(Point newCenter)
{
// blabla
}
// And of course the IList methods
public void Add(Point newPoint)
{
points.Add(newPoint);
}
}
public class Marker : IMask
{
private Spot mySpot;
private int blargh;
// Other fields
public void MarkeryMethod()
{
// Blabla
}
// HERE IS THE PROBLEM: Should I do this and repeat myself
public void MoveTo(Point newCenter) { mySpot.MoveTo(newCenter); }
// And here I'm REALLY starting to repeat myself
public void Add(Point newPoint) { mySpot.Add(newPoint); }
}
观察: 接口IMask不是从List继承的。它正在实现IList接口,而这又是implements ICollection, IEnumerable 假设Marker在语义上不是特殊的Spot。所以,即使我可以从Spot继承并解决问题,它也不是最好的解决方案。
答案 0 :(得分:6)
接口是建立一种契约,它将实现它的类将具有此方法。所以你可以做的是一个实现你的接口的absctract / base类,然后Marker和Spot类可以从基类继承而且你已经设置好了。
public abstract class BaseClass : IMask {...}
public class Marker : BaseClass{...}
public class Spot : BaseClass{...}
答案 1 :(得分:1)
在我看来,您的选择应该基于您对应用程序增长的期望,即向前兼容性。
如果你认为Marker会进化,例如也许有一天它会包含多个Spot,或者多个支持IMask的对象,然后重复自己是要走的路,因为你想要协调调用MoveTo和Add来包含所有对象在Marker中,你会很高兴Marker中有一层间接。
如果您认为Spot会发展,例如如果Spot要添加更多方法,如ChangeSize或Remove,也许最好的做法是将Spot作为Marker的公共属性公开,类型为IMask。这样就可以立即暴露新属性,而无需编写额外的包装代码。
答案 2 :(得分:0)
interface IMask : IList<System.Drawing.Point>
{
public void MoveTo(System.Drawing.Point newCenter);
// ...
public void
}
public class Mask : IMask
{
// ...
}
public class Spot
{
public Mask Mask = new Mask();
// ...
}
public class Marker
{
public Mask Mask = new Mask();
/// ...
}
为方便起见,您最好使用属性。