例如,单一责任原则说,例如 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);
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top