【发布时间】:2020-04-20 15:03:51
【问题描述】:
我有一个项目,涉及不同种类产品的网上商店。据我了解,如果您有多个从一个基类继承的类,那么工厂设计模式就是要走的路。我只是很难决定将实际决定使用哪个工厂的逻辑放在哪里。
我已经为不同种类的产品创建了类和工厂类。
public class Product
{
public int ID { get; protected set; }
public string Name { get; set; }
public ProductType Type { get; private set; }
public Product(int id)
{
ID = id;
Populate();
}
public virtual void CompleteOrder()
{
//SendMailToSupplier();
}
private void Populate()
{
//database stuff including setting the type
}
}
public class DigitalProduct : Product
{
public DigitalAsset ProductAsset { get; private set; }
public DigitalProduct(int id, DigitalAsset asset) : base(id)
{
ProductAsset = asset;
}
public override void CompleteOrder()
{
base.CompleteOrder();
//SendAssetToUser();
}
}
public class PrintProduct : Product
{
public PrintInformation Information { get; private set; }
public PrintProduct(int id, PrintInformation information) : base(id)
{
Information = information;
}
public override void CompleteOrder()
{
base.CompleteOrder();
//PreparePrintingFlle();
}
}
public abstract class ProductFactory
{
public abstract Product CreateProduct(int id);
}
public class GenericProductFactory : ProductFactory
{
public override Product CreateProduct(int id)
{
return new Product(id);
}
}
public class DigitalProductFactory : ProductFactory
{
public override Product CreateProduct(int id)
{
DigitalAsset asset = GetDigitalAsset(id);
return new DigitalProduct(id, asset);
}
private DigitalAsset GetDigitalAsset(int id)
{
DigitalAsset asset = new DigitalAsset();
//IO stuff
return asset;
}
}
public class PrintProductProductFactory : ProductFactory
{
public override Product CreateProduct(int id)
{
PrintInformation information = GetPrintInformation(id);
return new PrintProduct(id,information);
}
private PrintInformation GetPrintInformation(int id)
{
PrintInformation information = new PrintInformation();
//database stuff
return information;
}
}
现在,当订单完成时,会触发一个事件。
public void OrderCompleted(int orderId, List<int> productIds);
所以在这里我有一个 int 列表,我想从中制作产品对象,这样我就可以调用
CompleteOrder 对它们每个都有作用。问题是要知道我需要从填充函数中填写的数据库中获取产品类型的产品类型。
我能做的是在 ProductFactory 中创建一个函数 public ProductFactory GetFactory(int id)。但是工厂不能是抽象类。
另一种选择是在产品类中创建一个函数public static Product GetProduct(int id)。然后首先确定使用哪个工厂并返回创建的产品。
但这两个选项都感觉很奇怪。我错过了什么吗?还是其中一种是实际可行的方法?
干杯。
【问题讨论】:
-
基类不应该知道它的派生类;这将违反开闭原则。将
Populate中的逻辑放入您的工厂。 -
除了马格努斯的回答,我还要补充一点,感觉就像你错过了另一个分裂。如果一个订单可以由多个产品组成,那么一个产品可以完成一个订单是不对的。订单应该由可能的 OrderId、CustomerId、产品列表等组成。应该具有 CompleteOrder 功能。
-
@sr28 你是对的。这里的问题是我们正在使用第 3 方包,它只支持通过事件扩展他们的软件调用。所以我无法控制那部分
标签: c# factory-pattern abstract-factory