1

カスタムボタンを最初から作成したいとします。

  • BasicButton:NSObject
    そこで、ボタンがクリックされたときにマウスイベントを処理し、関心のある受信者にメッセージを転送する方法を知っているクラスを作成しました(委任、ターゲット/アクション、通知などを介して)。
  • SolidColorButton:BasicButton:NSObject
    ボタンは機能するようになりましたが、表示されないため、ボタンを生き生きとさせるために無地の背景を描画することにしました(UIデザインの点ではあまり良くありませんが、ふりをしてみましょう)。
  • LabelledButton:SolidColorButton:BasicButton:NSObject
    ここで、ボタンにラベルを追加したいとします。そこで、ボタンにテキストを描画できる別のサブクラスを作成しました。

これで、マウスイベントを処理し、無地の背景を描画し、テキストを描画できるボタンができました。しかし、単色ではなく背景の画像を含むボタンが必要だと判断した場合、ラベルの描画方法はわかりますが、どうなりますか?これは、単一継承のサブクラス化アプローチが失敗する場所です。マウスの処理、ラベルの描画、画像の描画を自由に組み合わせることができません。継承チェーンの下位レベルを選択することしかできません。

だから私の質問は、これらの別々のモジュールを実装して、それらを混合して一致させ、目的のモジュールの機能を組み合わせたものだけを備えたある種の子孫オブジェクトを作成する方法は何ですか?

たとえば、次のようなモジュールを記述できるようにしたいと思います。

  • マウスの取り扱い
  • キーボードの取り扱い
  • ソリッドバックグラウンド
  • 画像の背景
  • ラベル

次に、次のような特定のボタンを作成する機能があります。a)マウスを処理し、b)背景を描画し、c)ラベルを付けます。何もありません。

この質問は、Objective-Cまたは別の単一継承OOP言語でこれをどのように行うかに固有のものです。Rubyでは、これを行う方法はミックスインを使用することです。

4

2 に答える 2

3

ここでは、継承が悪い考えであることにすでに気づいています。デコレータパターンは便利です。1つのボタンクラスと、ボタンを「装飾」(ボタンをラップして機能を追加)し、任意に組み合わせることができる複数のデコレータがあります。

クラス図:

 +---------------+     innerButton
 |ButtonInterface+------------------------+
 +---------------+ 1                      |
        ^    ^                            |
        |    |                            |
        |    +-------------+              |
 +------+------+   +-------+-------+      |
 | BasicButton |   |ButtonDecorator+------+
 +-------------+   +---------------+
                     ^           ^
                     |           |  ...
                     |           |
+--------------------+----+ +----+------------------+
|SolidColorButtonDecorator| |LabelledButtonDecorator|  ...
+-------------------------+ +-----------------------+

オブジェクト図(例):

+----------------------------+
|MouseHandlingButtonDecorator|
+-----+----------------------+
      |
     1| innerButton
+-----+-------------------+
|BackgroundButtonDecorator|
+-----+-------------------+
      |
     1| innerButton
+-----+-----------------+
|LabelledButtonDecorator|
+-----+-----------------+
      |
     1| innerButton
+-----+-----+
|BasicButton|
+-----------+
于 2013-02-14T12:50:23.473 に答える
1

もう1つの選択肢は、コンポジションデザインパターンですが、「デコレータパターン」のように変更されています。

次の例は、描画動作にのみ適用され、マウスやキーボードの動作には適用されません。次のグラフのドットは無視してください。

注:C ++やC#に似ているため、Objective-cとのわずかな違いは無視してください。

まず、メンバーまたはアイテムに「描画」機能を「委任」するボタンクラスが必要です。まず、メインクラスだけを見てみましょう。

................................................................................
..+--------------------------------+..../|..+--------------------------------+..
..|        GraphicObjectClass      |.../.|..|      CompositeButtonClass      |..
..+--------------------------------*--<..|--*--------------------------------+..
..| [+]  void Draw(); <<virtual>>  |...\.|..| [+]  void Draw(); <<override>> |..
..+--------------------------------+....\|..+--------------------------------+..
................................................................................

ボタンが必要だとしましょう。

  • 境界線を引く「モジュールクラス」
  • 背景、単色、またはパターンを描画する「モジュールクラス」
  • テキストラベル、太字、斜体、フォント名を描画する「モジュールクラス」

2番目のグラフは、それを個別に実行する個別の「モジュール」またはクラスを示しています。

................................................................................
..+--------------------------------+............................................
..|        GraphicObjectClass      |............................................
..+--------------------------------+............................................
..| [+]  void Draw(); <<virtual>>  |............................................
..+---------------*----------------+............................................
..................|.............................................................
..................^.............................................................
................./.\............................................................
................/...\...........................................................
.............../--+--\..........................................................
..................|.............................................................
..+---------------*----------------+.../|...+--------------------------------+..
..|      ButtonComponentClass      |../.|...|      SolidColorButtonClass     |..
..+--------------------------------+-<..|-*.+--------------------------------+..
..| [+]  void Draw(); <<virtual>>  |..\.|.|.| [+]  void Draw(); <<override>> |..
..+--------------------------------+...\|.|.+--------------------------------+..    
..........................................|.....................................
..........................................|.+--------------------------------+..
..........................................|.|       LabeledButtonClass       |..
..........................................|.+--------------------------------+..
..........................................*-* [+]  void Draw(); <<override>> |..
..........................................|.+--------------------------------+..
..........................................|.....................................
..........................................|.+--------------------------------+..
..........................................|.|        BorderButtonClass       |..
..........................................|.+--------------------------------+..
..........................................*-* [+]  void Draw(); <<override>> |..
............................................+--------------------------------+..
................................................................................

コンポーネントをボタンに統合しましょう。継承の関連付けについて、他の関連付けとは異なるチャートを作成していることに注意してください。

.......................................................................................
.+--------------------------------------------+.....+--------------------------------+.
.|              CompositeButtonClass          |.....|      SolidColorButtonClass     |.
.+--------------------------------------------+.....+--------------------------------+.
.| [+] ButtonComponentClass* Background       *-----* [+]  void Draw(); <<override>> |.
.|                                            |.....+--------------------------------+.
.| [+] ButtonComponentClass* Border           *---*....................................
.|                                            |...|.+--------------------------------+.
.| [+] ButtonComponentClass* Label            *-*.|.|       LabeledButtonClass       |.
.+--------------------------------------------+.|.|.+--------------------------------+.
.| [+] void Draw();               <<virtual>> |.|.+-* [+]  void Draw(); <<override>> |.
.+--------------------------------------------+.|...+--------------------------------+.
................................................|......................................
................................................|...+--------------------------------+.
................................................|...|        BorderButtonClass       |.
................................................|...+--------------------------------+.
................................................*---* [+]  void Draw(); <<override>> |.
....................................................+--------------------------------+.
.......................................................................................

これで、メンバーまたはアイテムに「描画」機能を「委任」するボタンクラスができました。まず、メインクラスだけを見てみましょう。

virtual /* override */ void CompositeButtonClass::Draw()
{
   // [Background Draw]     
   this->Background->Draw();

   // [Border Draw]
   this->Border->Draw();

   // [Label Draw]
   this->Label->Draw();
}

ただの提案。

乾杯。

于 2013-02-14T18:14:07.613 に答える