代码之家  ›  专栏  ›  技术社区  ›  Joe Daley

在可扩展类层次结构中实现单一责任原则的技术/模式

  •  2
  • Joe Daley  · 技术社区  · 14 年前

    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 为每个子类测试 发票联 并运行适当的打印代码。这似乎不对。
    • 访客模式。问题在于,访问者界面需要在核心层中存在,并引用定制层中的类。我希望能够通过修改核心层在自定义层中添加新的子类。
    3 回复  |  直到 14 年前
        1
  •  1
  •   Don Roby    14 年前

    你可能想考虑一下 Acyclic Visitor (PDF) .

        2
  •  1
  •   NOtherDev    14 年前

    Invoice 类型,你只需要不同的 InvoicePrinter 传递给的类型 发票联 实例:

    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) 
            {
                ...
            }
        }
    }
    

    你应该有一个国际奥委会为你提供 实例。

        3
  •  1
  •   Saeed Amiri    14 年前

    我认为下面的解决方案对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);
        }
    }
    
    推荐文章