-1

次の場合を考えてみましょう-

PackTheFruit()、CutTheFruit()、CleanTheFruit()などのメソッドを持つクラス(Fruits)があります。このクラスは変更できません。

また、フルーツタイプのオブジェクトを含むクラスのセットもあります。一部のクラスでは、PackTheFruit()メソッドにアクセスしたいのですが、すべてではありません。

Fruitsクラスによって実装される2つのインターフェースを作成することを考えました。1つはPackTheFruit()を公開し、もう1つは他のメソッドのみを公開し、各クラスは、そのメソッドにアクセスする必要があるかどうかに応じて、代わりにこれらのインターフェイスタイプのオブジェクトを持ちます。

このソリューションの問題は、Fruitsクラスに別のメソッドを追加するたびに、インターフェイスを更新する必要があることです。それは少なくとも私の目には悪いデザインでしょう。

4

3 に答える 3

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;
    }
}

新しい機能のために新しいインターフェイスを追加する場合、既存のインターフェイスを変更する必要はありません。これはインターフェイス分離の原則(ISP) と呼ばれ、オブジェクト指向設計の 5 つの SOLID 原則の 1 つです。

注:IPackerインターフェイスを使用すると、さまざまな種類のパッカーを実装できます。ある実装では、パッケージ内にさまざまな種類の果物を混在させることができますが、別の実装では果物を並べ替えることができます。

于 2012-12-22T17:17:48.473 に答える
1

このようなことを意味しますか?

class Fruit
{
    public float Weight { get; set; }   
}

interface IPackable { }

class Apple : Fruit, IPackable
{

}

class FruitPacker
{
    void Pack(IPackable fruit)
    {
        // pack fruit
    }
}

果物はそれがどのように詰められているかを知る必要がないので、果物にそれを実装する必要はありません。

于 2012-12-22T16:07:28.137 に答える
1

おそらく、PackTheFruit()、CutTheFruit()、CleanTheFruit() メソッドは Fruit クラスに固有のものであってはなりません。名前は果物ではなく果物で行われているように聞こえます.

果物をパックする方法を知っている FruitPacker クラスを提供する場合、そのアクションを呼び出すことができるクラスのインスタンスに、このクラスのインスタンスを提供できます。他の方法についても同様です。

于 2012-12-22T16:22:49.297 に答える