按层次结构顺序对抽象类进行建模

时间:2019-06-13 03:05:14

标签: c#

我有一些抽象类,代表冰淇淋菜单项。我希望它们是分层的,意思是:

  • 基本:洒
  • 美食:鲜奶油,以及所有来自Basic(洒)的东西
  • 豪华:焦糖和美食佳肴中的一切(鲜奶油和巧克力粉)

下面是三个类。除了明确添加其他类的浇头之外,将这些类链接在一起以使Deluxe包含Gourmet和Basic的所有内容,而Gourmet包含Basic的所有内容的最佳方法是什么?在一个类中,我只需要链接构造函数即可。

public abstract class Basic : IceCream
{
    public Basic() : base("Basic")
    {
        _toppings.Add("Sprinkles");
    }
}

public abstract class Gourmet : IceCream
{
    public Gourmet() : base("Gourmet")
    {
        _toppings.Add("Whipped Cream"));
    }
}

public abstract class Deluxe : IceCream
{
    public Deluxe() : base("Deluxe")
    {
        _toppings.Add("Caramel"));
    }
}

1 个答案:

答案 0 :(得分:1)

根据我对这个问题的评论,您应该考虑使用组合而不是继承。

如果您从Basic实例开始(根据您现有的模型),因为客户说他们只是想撒些糖,但是最后一分钟他们说他们想要焦糖,那么您必须进行更改实例在运行时的类型。您不能通过继承模型做到这一点。但是使用成分,您只需添加焦糖即可。

ToppingToppingLevel的定义开始:

public enum ToppingLevel
{
    Basic,
    Gourmet,
    Deluxe,
}

public class Topping
{
    public string Name { get; private set; }
    public ToppingLevel Level { get; private set; }

    public Topping(string name, ToppingLevel level)
    {
        this.Name = name;
        this.Level = level;
    }
}

现在很容易创建浇头:

var sprinkles = new Topping("Sprinkles", ToppingLevel.Basic);
var whipped_cream = new Topping("Whipped Cream", ToppingLevel.Gourmet);
var caramel = new Topping("Caramel", ToppingLevel.Deluxe);

然后我们只需要为IceCream提供一个定义:

public class IceCream
{
    private List<Topping> _toppings = new List<Topping>();
    public void AddTopping(Topping topping)
    {
        _toppings.Add(topping);
    }
    public IEnumerable<Topping> Toppings { get => _toppings.ToArray(); }
    public ToppingLevel Level
    {
        get =>
            _toppings
                .OrderByDescending(x => (int)x.Level)
                .FirstOrDefault()?.Level ?? ToppingLevel.Basic;
    }
}

现在我可以这样写:

var icecream = new IceCream();
Console.WriteLine(icecream.Level);

icecream.AddTopping(sprinkles);
Console.WriteLine(icecream.Level);

icecream.AddTopping(whipped_cream);
Console.WriteLine(icecream.Level);

icecream.AddTopping(caramel);
Console.WriteLine(icecream.Level);

输出:

Basic
Basic
Gourmet
Deluxe

您可以看到,只需添加一个浇头即可更改冰淇淋的“级别”,而无需在运行时更改其Type