对类方法的动态控制访问
本文关键字:访问 动态控制 类方法 | 更新日期: 2023-09-27 17:49:21
考虑以下情况-
我有一个类(水果),它有一些方法,如PackTheFruit(), CutTheFruit(), CleanTheFruit()。这个类不能修改。
我还有一组类,其中包含一个水果类型的对象。在一些类中,我想访问PackTheFruit()方法,但不是全部。
我想创建两个接口,这将由水果类实现。一个将公开PackTheFruit(),另一个将只公开其他方法,每个类将拥有这些接口类型的对象,而不是取决于它们是否需要访问该方法。
这个解决方案的问题是,每当我向Fruits类添加另一个方法时,我都必须更新接口。至少在我看来,这是一个糟糕的设计。
这取决于这些操作在做什么。让我们假设包装包括将水果添加到最大重量的篮子中,那么您需要知道水果的重量以使其可包装。如果你想包装不同种类的水果,最好有一个单独的包装类。让水果自己包装感觉很奇怪。
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;
}
}
如果为新功能添加新接口,则不必更改现有接口。这被称为接口隔离原则(ISP),是面向对象设计的五个坚实原则之一。
注意:有一个IPacker
接口允许你实现不同种类的包装器。一个实现可以在一个包中混合不同种类的水果,而另一个实现可以对水果进行分类。
你是说这样吗?
class Fruit
{
public float Weight { get; set; }
}
interface IPackable { }
class Apple : Fruit, IPackable
{
}
class FruitPacker
{
void Pack(IPackable fruit)
{
// pack fruit
}
}
水果不需要知道是如何包装的,所以你不需要在水果中实现它。
也许你的PackTheFruit(), CutTheFruit()和CleanTheFruit()方法不应该是Fruit类固有的。这些名字听起来像是用一个水果做的,而不是由一个水果做的。
如果你提供了一个知道如何包装水果的FruitPacker类,你可以为那些应该能够调用该操作的类提供这个类的实例。其他方法也是一样。