2

単一責任の原則では、たとえば、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これは間違っているようです。
  • 来客パターン。問題は、ビジター インターフェイスがコア レイヤーに存在し、カスタマイズされたレイヤーのクラスへの参照が必要になることです。Core レイヤーを変更して、Customized レイヤーに新しいサブクラスを追加できるようにしたいと考えています。
4

3 に答える 3

1

非環式ビジター (PDF)を検討することをお勧めします。

于 2010-11-02T12:17:12.743 に答える
1

次のソリューションは C# に役立つと思います。exteraはありません。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);
    }
}
于 2010-11-02T09:15:54.087 に答える
1

請求書をサブクラス化する必要は本当にありますか? 請求書は、印刷以外に違いはありますか? いいえの場合、異なる型を持つ必要はありません。インスタンスに渡されるInvoice異なる型が必要なだけです。InvoicePrinterInvoice

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

InvoicePrinterまた、適切なインスタンスを提供するには、ある種の IoC が必要です。

于 2010-11-02T08:42:14.260 に答える