0

基本クラスとその継承を持つクラス階層を形成する多くのクラスがあります。各クラスは、いくつかの責任を負うことで非常に大きくなりますが、それらの責任は結合されていません。一貫して簡単に使用できるため、さまざまな責任をクラスにまとめています (明確に表現することはできません。図のコードを参照してください)。しかし、これは良い設計ではないようです。使いやすさを維持しながら大規模なクラスを分割するにはどうすればよいですか? あなたの提案とコメントをありがとう!以下は、イラストコードを見つけてください。

// Base class.
class Base
{
public:
    // For responsibility A
    virtual void A1();
    virtual void A2();
    ...

    // For responsibility B
    virtual void B1();
    virtual void B2();
    ...

    // More responsibilites.
    ...
};

// Derived class 1.
class Derived_1 : public Base
{...};

// More derived classes.
...

// A function use it.
void Fun()
{
    Base* p = new Derived_1;
    p->A1(); // Here A1 and B1 are binded in the class Base, thus it make sure
    p->B1(); // their uses are consistent. If they are separated, how to ensure it? 
}
4

2 に答える 2

2

クラスに複数の責任を持つことで、設計の単一責任原則に違反しています。

一般に、優れた設計はSOLIDの原則に従います。

クラスを分割します。

  1. 責任ごとにインターフェースを定義します。
  2. 多重継承を使用しないようにしてください。代わりに合成を使用してください。

概念を説明するために、いくつかのサンプル コードを追加しました。

#include <iostream>

//Interface for A
class ResponsibilityA
{
    public:
    virtual ~ResponsibilityA(){};
        virtual void A1() = 0;
        virtual void A2() = 0;
};


//Interface for B
class ResponsibilityB
{
        public:
    virtual ~ResponsibilityB(){};
        virtual void B1() = 0;
        virtual void B2() = 0;
};

//Concrete classes for each interface
class ResponsibilityAExecutor : public ResponsibilityA
{
        public:
        virtual void A1(){ std::cout<<"A1 executed\n"; };
        virtual void A2(){ std::cout<<"A2 executed\n"; };
};

class ResponsibilityBExecutor : public ResponsibilityB
{
        public:
        virtual void B1(){ std::cout<<"B1 executed\n"; }
        virtual void B2(){ std::cout<<"B2 executed\n"; }
};

// Now we use the interface implementations in a class that needs
// to combine both responsibilities
class PlanExecutor
{
public:
        PlanExecutor( ResponsibilityA& a, ResponsibilityB& b ) : 
        a_(a),
        b_(b)
        {

        }
        void ExecutePlan()
        {
                std::cout<<"Executing first part of the plan:\n";
                a_.A1();
                b_.B1();
                std::cout<<"Executing second part of the plan\n";
                a_.A2();
                b_.B2();
        }
private:
        ResponsibilityA &a_;
        ResponsibilityB &b_;    
};

int main()
{
        ResponsibilityAExecutor a;
        ResponsibilityBExecutor b;
        PlanExecutor p(a,b);
        p.ExecutePlan();
        return 0;
}

最後に、ネーミングの重要性も強調する必要があります。

于 2013-02-05T01:42:29.090 に答える
0

AとBの責任がまったく異なる場合、両方に別々のクラスを作成し、子供にこの方法で必要なものを実装させ、一部の子供はAのみ、Bのみ、または両方を必要とし、それを管理および保守可能に保ちます

// Base class.
class Base
{
public:
    // For responsibility A
**Goes to class A**
    virtual void A1();
    virtual void A2();
    ...


**//Goes to class B**
    // For responsibility B
    virtual void B1();
    virtual void B2();
    ...

    // More responsibilites.
    ...
};

// Derived class 1.
class Derived_1 : public Base **//inherits from A**
{...}; 

class Derived_2:Public A,Public B
于 2013-02-05T01:33:57.100 に答える