0

さまざまな責任をまとめるためのコード。コードは短く、使いやすいようです。

// Base class.
class A
{
public:
    // Native responsibility.
    virtual void F();

    // Show it with graphics.
    virtual void ShowGraphics();

    // Show it with table.
    virtual void ShowTable();

    // IO
    virtual void Read();
    virtual void Write();
};

// A number of concrete classes derive from base class.
class B : public A
{
public:
    // Native responsibility.
    virtual void F();

    // Show with graphics.
    virtual void ShowGraphics();

    // Show with table.
    virtual void ShowTable();

    // IO
    virtual void Read();
    virtual void Write();

private:
    // Include attributes required for native responsibility. 
    // Include attributes required for showing with graphics. 
    // Include attributes required for IO. 
    // Include attributes required for showing with table. 
};

例としてグラフィックの責任を使用して、責任を分離するコード。コードははるかに長くなります。それは本当にそれに値しますか?

class AGraphics;
class BGraphics;

class A
{
public:
    // Native responsibility.
    virtual void F();

    // Create AGraphics for showing with graphics.
    virtual AGraphics* CreateGraphics(); // ShowGraphics() becomes
                                         // CreateGraphics().Show().
                                         // For IO and showing table
                                         // do similarly.
                                         // Is this design okay???

    virtual ATable* CreateTable();                                             
    virtual AIo* CreateIo();                                             
};
// for the above code, does a follow singe responsibility principle?

class B : public A
{
public:
    // Native responsibility.
    virtual void F();

    // Create AGraphics for showing with graphics.
    virtual BGraphics* CreateGraphics();
    virtual BTable* CreateTable();                                             
    virtual BIo* CreateIo();                                             

private:
    // Include attributes required for native responsibility.
};

class AGrahics
{
public:
    // Show with graphics.
    virtual void ShowGraphics();
};

class BGrahics : public AGrahics
{
public:
    // Show with graphics.
    virtual void Show();

public:
    B* b; // need B's data attributes.
    // Include attributes required for showing with graphics. 
};
4

2 に答える 2

1

1) 実装に依存します。実装が単純で理解しやすい場合は、複雑さを軽減するために 1 つのクラスにまとめることができます。ただし、実装が大規模で複雑な場合は、複雑さを軽減するために異なるクラスに分割することをお勧めします。
2) 用途によります。単体テストを作成し、それに応じてインターフェイスをリファクタリングしてみてください。さまざまな機能を個別にテストするのは簡単です。テストが容易であれば、再利用も容易です。

于 2013-02-05T02:41:51.487 に答える
1

Gamma 氏らによる優れた "Design Patterns" という本では、頻繁に変更される可能性のあるものを、変更される可能性が低いものから分離することについて説明しています。一般的に言えば、何かを表現する方法 (グラフィックス、テーブル) のコードは、それ自体のコードよりも頻繁に変更されます。

したがって、問題をさまざまなクラスに分離するのに苦労する理由の 1 つは、それぞれが 1 つのことを適切に行う小さなクラスになってしまうことです。後で、たとえば、テーブル出力の外観に機能を追加することにした場合、IO とグラフィックスに関するすべてのコードを苦労する必要はありません。(クラスが分離されている場合) コンテインメントを使用するのは余分な作業のように思えますが、問題についての考えを明確にするのに役立つという副次的な利点があります。別の部分の動作に影響を与えるコード。

于 2013-02-05T03:21:00.493 に答える