在可扩展类层次结构中实现单一责任原则的技术/模式
-
28-09-2019 - |
题
例如,单一责任原则说,例如 Invoice
类不应包含要自行打印的代码。打印应分为不同的类。
但是假设您有一个层次结构 Invoice
该软件不同层中的课程:
namespace CoreLayer {
public class Invoice {
public virtual void Print() {
...
}
}
}
namespace CustomizedLayer {
public class LaborInvoice : Invoice {
public override void Print() {
...
}
}
public class AccountInvoice : Invoice {
public override void Print() {
...
}
}
}
哪些技术或设计模式可以用来分开印刷重新性?
想法:
- 一个很大的单独课程
if
对每个子类测试的陈述Invoice
并运行适当的打印代码。这似乎是错误的。 - 访客模式。问题在于,访问者界面需要在核心层中存在,并引用自定义层中的类。我希望能够通过修改核心层在自定义层中添加新的子类。
解决方案
您可能想考虑 无环访客(PDF).
其他提示
您真的需要子类发票吗?发票在其他方面是否有所不同?如果没有,则无需不同 Invoice
类型,您只需要不同 InvoicePrinter
类型传递给 Invoice
实例:
namespace CoreLayer
{
public class IInvoicePrinter
{
void Print(Invoice invoice);
}
public class Invoice
{
}
}
namespace CustomizedLayer
{
public class LaborInvoicePrinter : IInvoicePrinter
{
public void Print(Invoice invoice)
{
...
}
}
public class AccountInvoicePrinter : IInvoicePrinter
{
public void Print(Invoice invoice)
{
...
}
}
}
而且您应该有某种IOC为您提供适当的 InvoicePrinter
实例。
我认为波纹管解决方案对C#很有用,它没有外观 if
, ,我知道,使用 visitor
不推荐图案。
public class InvoicePrinterManager
{
public void Print(AccountInvoice invoice)
{
AccountInvoicePrinter p1 = new AccountInvoicePrinter(invoice);
p1.print();
}
public void Print(LaborInvoice invoice)
{
LaborInvoicePrinter p1 = new LaborInvoicePrinter(invoice);
p1.print();
}
}
public class InvoicePrinter<T> where T : Invoice, new()
{
T instance;
public InvoicePrinter(T invoice)
{
if (invoice != null)
{
this.instance = invoice;
}
else
instance = new T();
}
public virtual void Print()
{
/// Arrange objects as you want and print them.
}
}
public class AccountInvoicePrinter : InvoicePrinter<AccountInvoice>
{
public AccountInvoicePrinter(AccountInvoice invoice)
: base(invoice)
{
}
public override void Print()
{
/// todo
}
}
public class LaborInvoicePrinter : InvoicePrinter<LaborInvoice>
{
public LaborInvoicePrinter(LaborInvoice invoice)
: base(invoice)
{
}
public override void Print()
{
/// todo: use instance
}
}
public class Test
{
public void TestPrint()
{
LaborInvoice li = new LaborInvoice();
InvoicePrintManager printerManager = new InvoicePrintManager();
printerManager.Print(li);
}
}
不隶属于 StackOverflow