C#中的工厂模式

now*_*ed. 1 .net c# design-patterns .net-4.5

我有点能够理解工厂模式并想出了这个实现。

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,
}
Run Code Online (Sandbox Code Playgroud)

我的整个想法(从理论理解)是 GetFruitWeights 函数应接受枚举类型,然后返回水果重量。我能够获得特定 Fruit 的对象,但现在坚持如何从 Fruit 对象中获取水果的重量。

另外,添加到我的疑虑清单中,我真的在这个实现中遵循工厂模式吗?而且,互联网上的一些材料也使用抽象类?我应该遵循什么?接口实现还是应该使用抽象类并覆盖它?

在此先感谢您的帮助。

Jam*_*mes 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果你不打算使用fruit对象的话,我会重新命名你的方法GetFruit,回报IFruits(不盒),并调用ReturnFruitWeightfruit实例为重。

在这个实现中我真的遵循工厂模式吗?

工厂模式的重点是允许您在不知道具体类型的情况下创建对象,所以是的,您在这里拥有的是工厂方法模式的一个相当基本的示例。

互联网上的一些材料也使用抽象类?我应该遵循什么?接口实现还是应该使用抽象类并覆盖它?

这完全取决于您的应用程序设计。例如,我个人只会在以下情况下引入抽象基类:

  • 我可以在所有课程中共享通用代码
  • 我需要确定某个特定类的一些方法属于一个家族的特定类型的,即Banana是一个类型的Fruit

除此之外,我可能几乎总是采用接口类型的方法。请记住,您可以同时拥有两者,没有理由不能拥有支持特定接口的抽象基类......