首页 > 解决方案 > Model abstract classes in a hierarchical order

问题描述

I have some abstract classes representing ice cream menu items. I want them to be hierarchical, meaning:

Below are the three classes. What is the best way, aside from explicitly adding the toppings from the other classes, to link the classes together such that Deluxe contains everything from Gourmet and Basic, and Gourmet contains everything from Basic? In a single class, I would just chain the constructors.

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

标签: c#

解决方案


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

如果您从Basic(根据您现有的模型)的实例开始,因为客户说他们只是想要洒,但在最后一刻他们说他们想要焦糖,那么您必须在运行时更改实例的类型-时间。你不能用继承模型做到这一点。但是有了成分,你只需添加焦糖就可以了。

Topping从and的定义开始ToppingLevel

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

输出:

基本的
基本的
美食
豪华

您可以看到,通过简单地添加浇头,我已经更改了冰淇淋的“级别”,而无需Type在运行时更改它。


推荐阅读