2

Factory Pattern を少し理解できたので、この実装を思い付きました。

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Enter the fruit name to get the Fruit!");
        string fruit = Console.ReadLine();

        FruitsList fruits;
        if (Enum.TryParse(fruit, true, out fruits))
        {
            var fruitWeight = GetFruitWeight(fruits);
            Console.ReadLine();
        }
        else
        {
            Console.WriteLine("Fruit Name is undefined!");
            Console.ReadLine();
        }
    }

    private static object GetFruitWeight(FruitsList fruitNumber)
    {
        switch (fruitNumber)
        {
            case FruitsList.Banana:
                return new Banana();
            case FruitsList.Apple:
                return new Apple();
        }

        return null;
    }
}

internal class Banana : IFruits
{
    public float ReturnFruitWeight()
    {
        return (float)10.00;
    }
}

public interface IFruits
{
    float ReturnFruitWeight();
}

public class Apple : IFruits
{
    public float ReturnFruitWeight()
    {
        return (float)30.00;
    }
}

public enum FruitsList
{
    Apple,
    Banana,
}

(理論的な理解からの)私の全体的な考えは、 GetFruitWeights 関数が列挙型を受け入れてから果物の重量を返すということです。特定のフルーツのオブジェクトを取得できましたが、フルーツ オブジェクトからフルーツの重量を取得する方法に行き詰まりました。

また、私の疑問リストに追加するために、この実装で本当に Factory パターンに従っているのでしょうか? また、インターネットの一部の資料では、抽象クラスも使用されていますか? 何に従うべきですか?インターフェイスの実装ですか、それとも抽象クラスを使用してオーバーライドする必要がありますか?

よろしくお願いします。

4

4 に答える 4

5

オブジェクトが返されたときにそのオブジェクトを使用するつもりがない場合fruitは、フルーツ オブジェクトではなく、単純に重量を直接返します。ファクトリメソッド名は、実際にはオブジェクトではなく重みを返すと言っているので、理論的には正しいアプローチです。

const float AppleWeight = 10;
const float BananaWeight = 10.4;
...
public static float GetFruitWeight(FruitList fruitType)
{
    switch (fruitType)
    {
        case FruitsList.Apple:
            return AppleWeight;
        case FruitsList.Banana:
            return BananaWeight;
        default:
            return 0;
    }
}

ただし、fruitオブジェクトを使用する場合は、メソッドの名前を に変更しGetFruit、戻りIFruits(ボックス化しないでください) 、重みReturnFruitWeightのインスタンスを呼び出します。fruit

この実装では、本当に Factory パターンに従っていますか?

ファクトリ パターンのポイントは、具象型を知らなくてもオブジェクトを作成できるようにすることです。したがって、ここにあるのはファクトリ メソッド パターンのかなり基本的な例です。

インターネットの一部の資料も抽象クラスを使用していますか? 何に従うべきですか?インターフェイスの実装ですか、それとも抽象クラスを使用してオーバーライドする必要がありますか?

これはすべて、アプリケーションの設計に依存します。たとえば、個人的には、次の場合にのみ抽象基本クラスを導入します。

  • クラス全体で共有できる共通のコードがあった
  • 特定のクラスが特定のタイプのファミリに属しBananaていること、つまりのタイプであることを判断する何らかの方法が必要でしたFruit

それ以外では、ほとんどの場合、インターフェイス型のアプローチを採用するでしょう。特定のインターフェイスをサポートする抽象基本クラスを使用できない理由はありません...

于 2013-05-06T08:26:44.097 に答える
1

objectではなく、 を返しIFruitsます。また、重量ではなく果物を返すように、静的メソッドの名前を変更します。

private static IFruits GetFruit(FruitsList fruitNumber)
{
    switch (fruitNumber)
    {
        case FruitsList.Banana:
            return new Banana();
        case FruitsList.Apple:
            return new Apple();
    }

    return null;  // Maybe you can throw a ArgumentException here
}
...
var theFruit = GetFruit(fruits);
var weight = theFruit.ReturnFruitWeight();

abstract classvsの場合interface、両方のオプションが有効です。メソッドにデフォルトの実装を提供したくない場合は、複数のインターフェイスを実装できますが、複数のクラスから継承できないため、インターフェイスの方が適している可能性があります。

于 2013-05-06T08:31:04.900 に答える
1

私はこのようなことをします:

public interface IFruit
{
    string Name { get; set; }
    decimal GetWeight();
}

public class Fruit : IFruit
{
    protected decimal Weight;

    public string Name { get; set; }

    public decimal GetWeight()
    {
        return Weight;
    }
}

public class Apple : Fruit
{
    public Apple()
    {
        Name = "Granny Smith";
        Weight = (decimal) 2.1;
    }
}

public class Banana : Fruit
{
    public Banana()
    {
        Name = "Cavendish";
        Weight = (decimal) 1.5;
    }
}

public enum FruitType
{
    Apple,
    Banana        
}

public static class FruitFactory
{
    public static IFruit CreateFruit(FruitType f)
    {
        switch(f)
        {
            case FruitType.Banana: return new Banana();
            case FruitType.Apple: return new Apple();
            default: return null;
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        var apple = FruitFactory.CreateFruit(FruitType.Apple);
        var banana = FruitFactory.CreateFruit(FruitType.Banana);

        Console.WriteLine(apple.Name + " " + apple.GetWeight());
        Console.WriteLine(banana.Name + " " + banana.GetWeight());
    }
}
于 2013-05-06T08:49:34.033 に答える