【发布时间】:2023-04-02 15:36:01
【问题描述】:
我正在自动化仓库,我正在尝试为下一个任务创建域模型:
仓库有很多产品。产品可以是液体的,也可以是杂货的,也可以是一块一块的。仓库中有两条包装线,用于包装液体产品或所有其他产品。逐件产品不需要包装。
这是我的模型:
enum ProductType
{
Liquid,
Grossery
}
interface IProduct
{
ProductType ProductType { get; }
}
interface IPackedProduct : IProduct
{
bool IsPacked { get; }
}
interface ILiquidProduct : IProduct
{
}
interface IGrosseryProduct : IProduct
{
}
interface IPackingLine
{
IPackedProduct Pack(IProduct product);
}
interface IGrosseryPackingLine : IPackingLine
{
IPackedProduct Pack(IGrosseryProduct p);
}
class ProductPackingLine : IPackingLine
{
public IPackedProduct Pack(IProduct product)
{
Console.WriteLine("Packing {0} default packing line", product);
return new PackedProduct(product);
}
}
class LiquidsPackingLine : IPackingLine
{
public IPackedProduct Pack(ILiquidProduct product) // I want this <=======================
{
Console.WriteLine("Packing {0} by liquid packing line", product);
return new PackedProduct(product);
}
}
class GrosseryPackingLine : IPackingLine
{
public IPackedProduct Pack(IProduct product)
{
Console.WriteLine("Packing {0} by grossery packing line", product);
return new PackedProduct(product);
}
}
我是这样使用的:
IProduct milk = new LiquidProduct(ProductType.Liquid);
IProduct pasta = new GrosseryProduct(ProductType.Grossery);
var packer = new PackingManager();
IPackedProduct packedMilk = packer.Pack(milk);
IPackedProduct packedPasta = packer.Pack(pasta);
这里是 PackingManager
class PackingManager
{
public IPackedProduct Pack(IProduct product)
{
IPackingLine pl = GetPackingLineByProduct(product);
return pl.Pack(product);
}
private IPackingLine GetPackingLineByProduct(IProduct product)
{
switch (product.ProductType)
{
case ProductType.Liquid:
return new LiquidsPackingLine();
case ProductType.Grossery:
return new GrosseryPackingLine();
default:
throw new InvalidOperationException();
}
}
}
问题是,如果我使用IPackingLine.Pack(IProduct p),我可能会错误地将ILiquidProduct 的对象传递给错误的包装线。但是我需要我所有的包装线来实现IPackingLine,以便能够以更常见的方式使用它们。
如何避免这种情况?
【问题讨论】:
-
您似乎需要使用泛型,这样您就可以限定给定打包程序可以打包的东西种类。猜测语言,参见例如docs.microsoft.com/en-us/dotnet/csharp/programming-guide/…
-
您的
PackingManager违反了打开关闭原则。为什么需要通用/通用PackingManager? -
我需要有人来确定使用哪条包装线。在其他情况下,逻辑将分布在整个应用程序中。关于
GetPackingLineByProduct- 这里只是为了简单起见。在真正的应用程序中,我将注入一个工厂,它将构建我IPackingLine -
假设
PackingManager这是应用程序的某种服务层。
标签: oop interface domain-driven-design abstraction