考虑以下情况 -
我有一个类(Fruits),它有一些方法,如PackTheFruit(),CutTheFruit(),CleanTheFruit()。此类无法修改。
我还有一组包含水果类型对象的类。在某些类中,我希望能够访问PackTheFruit()方法,但不能访问所有类。
我曾想过创建两个接口,这些接口将由Fruits类实现。一个人会暴露PackTheFruit(),一个人只会暴露其他方法,每个类都有一个这些接口类型的对象,而不是取决于他们是否需要访问该方法。
这个解决方案的问题是,当我向Fruits类添加另一个方法时,我将不得不更新接口。至少在我看来这将是一个糟糕的设计。
答案 0 :(得分:1)
你的意思是这样的吗?
class Fruit
{
public float Weight { get; set; }
}
interface IPackable { }
class Apple : Fruit, IPackable
{
}
class FruitPacker
{
void Pack(IPackable fruit)
{
// pack fruit
}
}
水果不必知道如何包装,所以你不必在水果中实现它。
答案 1 :(得分:1)
也许你的PackTheFruit(),CutTheFruit()和CleanTheFruit()方法不应该是Fruit类固有的。这些名字听起来像用一个水果而不是通过一个水果。
如果您提供了一个知道如何打包水果的FruitPacker类,您可以为应该能够调用该操作的类提供此类的实例。其他方法也是如此。
答案 2 :(得分:1)
我取决于这些操作正在做什么。我们假设包装包括将水果添加到最大重量的篮子中,然后您需要知道水果的重量以使其可以包装。如果你想要包装不同种类的水果,最好有一个单独的包装类。将水果包装起来感觉很奇怪。
public interface IPackable
{
public float Weight { get; set; }
}
public interface IPacker
{
// Returns a list of packages represented by lists of fruits.
List<List<Fruit>> GetPackages(IEnumerable<Fruit> fruits, float maxPackageWeight);
}
public class Packer : IPacker
{
public List<List<Fruit>> GetPackages(IEnumerable<Fruit> fruits,
float maxPackageWeight)
{
var currentPackage = new List<Fruit>();
var packages = new List<List<Fruit>>(currentPackage);
float currentWeight = 0.0f;
foreach (Fruit fruit in fruits) {
var packable = fruit as IPackable;
if (packable != null && packable.Weight <= maxPackageWeight) {
if (currentWeight + packable.Weight <= maxPackageWeight) {
currentPackage.Add(fruit);
currentWeight += packable.Weight;
} else {
var currentPackage = new List<Fruit>(fruit);
packages.Add(currentPackage);
currentWeight = packable.Weight;
}
}
}
return packages;
}
}
如果为新功能添加新接口,则无需更改现有接口。这称为Interface segregation principle(ISP),是面向对象设计的五个SOLID原则之一。
注意:拥有IPacker
界面可以实现不同类型的打包程序。实现可能会在包中混合不同种类的水果,而另一种可能会对水果进行排序。