2

だから私はこれについて考えるのに時間を費やし、「解決策」を探してグーグル全体に行きました(解決策はおそらく好みの問題ですが、私はこれについて確信が持てません)。以下は私が抱えている問題ですが、この問題は構成に関する多くの状況に適用できます。

赤、緑、青、およびアルファのメンバーを含むクラス Color があります。これらにはそれぞれ set および get メンバー関数があります。十分に単純です。

class Colour
{
    public:
        float getRed();
        void setRed(float);
        float getGreen();
        void setGreen(float);
        ...
    private:
        float red;
        float green;
        ...
};

たとえば、このクラスを他のクラス内で使用して、それらの色を指定します (簡潔にするためにコンストラクターとデストラクターは省略します)。

class ColourableObject
{
    private:
        Colour colour;
};

今、私の問題は次のとおりです: この ColourableObject クラスは、この Color オブジェクトにどのようにアクセスするのが最適でしょうか? 次のように、Color オブジェクトを取得してそのメンバー関数に直接アクセスするのが最善でしょうか。

class ColourableObject
{
    public:
        Colour& getColour();
    private:
        Colour colour;
};

または、次のように、ColourableObject クラスに独自のセットを与えて、Color オブジェクトに作用する色の関数を取得する方がよいでしょうか。

class ColourableObject
{
    public:
        float getRed();
        void setRed(float);
        ...
    private:
        Colour colour;
};

私にとっては、この Color オブジェクトを直接操作するだけで、この Color オブジェクトを必要とする各クラスに機能を追加する手間を省くことができるため、前者が最も論理的です。

しかし、後者は ColourableObject クラスへの変更の影響を受けやすいのではないでしょうか? get と set が互いに衝突するため、 colorableObject.getColour().setRed(x) は私にはあまり自然に思えないことは言うまでもありません。

私はおそらく完全に間違ったアプローチをしています。私はC++に比較的慣れていないので、喜んで学びます!問題は、前者の方法を使用するか、後者の方法を使用するか、またはまったく異なる方法を使用するかです。

4

6 に答える 6

4

あなたの質問に直接答えるつもりはありませんが、すべてのセッターを取り除き(通常、いずれにせよセッターを持つことは悪い兆候です)、コンストラクターを使用します:

Color c = Color( 123, 17, 77 );

ここで、3 つのコンストラクタ パラメータは RGB 値です。

于 2010-01-04T19:52:34.390 に答える
1

オレンジ、パープル、シアン、またはクレヨラの新しいスムーキー アップルウッドなどの他の色を追加する必要がある場合に備えて、クラスを再作成します。

基本色クラスのようなもので、新しい色を導入することでその基本クラスに作用します。そうすれば、あなたが扱っている色は関係ありません。すべてブラックボックスです。また、setColor および getColor の名前メソッドを再定義する必要がない色は問題ではないため、2 番目の質問にも答えます。彼らは、あなたが何色を指しているのかを知る必要も気にする必要もありません。

コード コンプリート (本) には、get/set メソッドが多すぎるクラスを参照することについて少し理解を深めるためのセクションがあったと思います。それは通常、物事の間違ったやり方に要約されます。

于 2010-01-04T19:53:46.807 に答える
1

この場合のゲッターとセッターの使用はあまり意味がありません。floatメンバーをColourpublicにすることもできます。複数のプライベートメンバーの検証または操作を行う必要がない限り、先に進んでそれらをパブリックにし、適切に初期化するコンストラクターを作成してColourください。

に関してはColourableObject、次の質問をする必要があります: 他の無関係なクラスがオブジェクトのColourメンバーにアクセスする必要がありますか? 彼らはそれを変更する必要がありますか?これらのいずれかに対する答えが「いいえ」である場合、そのオブジェクトにはいかなる種類のゲッターまたはセッターも持つべきではないと言えます。それ以外の場合は、検証または追加の状態変更を行う必要がない限り、Colour公開するだけです。

于 2010-01-04T19:54:38.350 に答える
1

DRY 原則は、オブジェクトへのアクセスを提供する最初のオプションをサポートしますColour

さらに、変更したい場合があります

    Colour& getColour();

    const Colour& getColour();
    void setColour( const Colour& );

...これにより、ColourableObjectいつ色が変わったかを常に知ることができます。

于 2010-01-04T19:55:28.660 に答える
1

最終的に、答えは、埋め込まれた Color オブジェクトへのアクセスをどのように制限したいか (または制限したくないか) によって異なります。

第一志望で…

class ColourableObject
{
public:
    Colour& getColour();
private:
    Colour colour;
};

...あなたは本当にアクセスをまったく制限していません。ユーザーが を介して非公開メンバーにアクセスできる場合、getColour()それを非公開にする意味は何ですか? 中間ステップをスキップして、これを実行することもできます。

class ColourableObject
{
public:
    Colour colour;
};

このようにすると、データ メンバーとそのすべての関数を直接参照できますC.colour.getRed();(C が ColourableObject であると仮定します)。

ここで、何らかの方法でエンド ユーザーを制限したいとします。エンド ユーザーは緑または青を設定できませんが、赤を設定できるようにします。その場合、2 番目の選択肢を使用することをお勧めします。

class ColourableObject
{
public:
    float getRed();
    void setRed(float);
    ...
private:
    Colour colour;
};

これは、 のユーザーがColourableObjectパブリック関数にのみアクセスでき、基になるプライベート メンバーにはアクセスできないためです。この理論的根拠は、エンド ユーザーと色の選択の間に何らかの中間ステップが必要な場合にも当てはまります。たとえば、次のようになります。

class ColourableObject
{
public:
    void setMood(enum Mood);
private:
    Colour colour;
};

void ColourableObject::setMood(enum Mood)
{
   if(Mood == HAPPY) colour.setRed(3);
   if(Mood == SAD)  colour.setBlue(11);
   ...
}

colour最後に、データ メンバーをパブリックに保ちながら、そのデータ メンバーに追加のアクセサーを追加するハイブリッドを実行できます。

概要:

  • 最初の方法:

    • 長所: Interface to Color は引き継がれます。
    • 短所: データ メンバーを公開します。
  • 2 番目の方法:

    • 長所: データをカプセル化します。Colour のインターフェースに対する今後の変更は、エンド ユーザーのコードではなく、コードを壊すだけです。
    • 短所: エンド ユーザーが使用できるようにする Colour のインターフェイスのすべての部分を再実装する必要があります。
于 2012-03-29T01:44:41.940 に答える
0

個人的には、Colorableのメンバーの場合、「get」の部分を削除したいと思います。

colorableObject.Color().setRed(1.0f);

あなたが言ったように、これは完全に個人的な好みです(スペルもそうです!:)が、このように、私にはそれはゲッター/セッターメソッドではなく「プロパティ」のように見えます。

于 2010-01-04T21:48:08.773 に答える