c# - Model abstract classes in a hierarchical order
问题描述
I have some abstract classes representing ice cream menu items. I want them to be hierarchical, meaning:
- Basic: Sprinkles
- Gourmet: Whipped cream, and everything from Basic (sprinkles)
- Deluxe: Caramel, and everything from Gourmet (whipped cream and sprinkles)
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"));
}
}
解决方案
根据我对这个问题的评论,您应该考虑使用组合而不是继承。
如果您从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
在运行时更改它。
推荐阅读
- python - 如何在给定的时间间隔内随机调用函数?- Python
- android - webview权限android pie
- c# - 如何在 C# 中迭代时从嵌套列表中删除所有项目
- android - 网站无法识别保存在 Smartlock 中的凭据
- amazon-ec2 - 如何创建可以休眠的 ec2 实例?
- python - __invert__ 方法
- c# - 标签属性上的 WPF MultiDataTrigger 仅触发一次
- c# - 使用自定义 dll 时 SISS 包损坏
- javascript - 逗号分隔、冒号或破折号分隔值的 MAC 地址正则表达式验证
- google-chrome - Joomla 页面有多少级缓存