2016-04-25 2 views
1

のは、私は3つの異なるクラスを実装したいとしましょう:スクエアColoredSquareTexturedSquareを。継承の深さ、シングルresponsabilityまたはDRY

ColoredSquareが色とスクエアTexturedSquareはテクスチャとColoredSquareであるので、私の最初の考えはそれらすべてが互いに由来持っていた:

class Square { 
    Square::Square(position) 
     : position_(position) 
    { 
    } 
} 

class ColoredSquare : public Square { 
    ColoredSquare::ColoredSquare(position, color) 
     : Square(position), color_(color) 
    { 
    } 
} 

class TexturedSquare: public ColoredSquare { 
    TexturedSquare::TexturedSquare(position, color, texture) 
     : ColoredSquare(position, color), texture_(texture) 
    { 
    } 
}; 

しかし、私は、あまりにも多くの継承の深さが悪い習慣であったことを読んで思い出しました(そして、一般的に、クラスは抽象クラスからのみ派生するべきです)。 は、だから私は、単一のクラスへの切り替えについて考えた:

class Square { 
    Square::Square(glm::vec3 position) 
     : position_(position), type_(SquareType::Basic) 
    { 
    } 

    Square::Square(glm::vec3 position, glm::vec4 color) 
     : position_(position), color_(color), type_(SquareType::Colored) 
    { 
    } 

    Square::Square(glm::vec3 position, glm::vec4 color, glm::vec2 texture) 
     : position_(position), color_(color), texture_(texture), type_(SquareType::Textured) 
    { 
    } 
}; 

、私はそれが許容できる今、私はそれが将来的に実用的であるかもしれないと思っていますを見つけるしながら、(私はポリモーフィズムを使用することはできません)これがSingle Responsability Principleに違反しているのではないかと思います。

この階層構造をきれいに広範囲に実装するにはどうすればよいでしょうか?

+0

私は2段階の継承はどのような手段でも「あまりにも多い」とは感じません。基本クラスが意味のあるオブジェクトであれば、抽象クラスである必要はありません。 – Unimportant

+0

ColouredTexturedSquareがありますか? –

+0

@Aer、私はあなたの最初のコードブロックは、あなたがそれを意味しているとは言えません - 第3のクラス定義(1)は 'TexturedSquare'ではなく、' ColoredSquare'であり、(2) 'Square'ではなく' ColoredSquare'をベースクラスとして使用していますか? –

答えて

1

私はこの質問に1つの正解があるとは思わないが、利用できる他の方法がある。

一つは、純粋仮想クラスを継承し、派生クラスでそれらを実装乗算することができます

class Texture {}; 
class Color {}; 
class Square {}; 

class ITextured { public: virtual void setTexture(Texture) = 0; }; 
class IColored { public: virtual void setColor(Color) = 0; }; 

class ColoredSquare : public IColored, public ITextured, public Square { 
    Texture tex; 
    Color col; 
public: 
    virtual void setTexture(Texture t) { tex = t; } 
    virtual void setColor(Color c) { col = c; } 
}; 

これは、長方形のメソッドが派生したまま、高さのみを変更するかもしれませんがRectangleからSquare継承のような問題を抱えて回避正方形のクラスに違反しています。

Compositionは、同様のアイデアを実装する方法がたくさんあります。

+0

ああ、それは面白いです。私はこれを考えなかった。それは私が考えることができる問題を解決します。 今、あなたは 'Composition'と言います。ここでは、継承するのではなく、あなたのソリューションに非常に似ています。 – Aer

+0

[これは継承を使用しない例です](https://ideone.com/qcnICT) – maxlazar

関連する問題