ロゴ
ホーム 提案事例 Obxetoについて 問い合わせ

1. なぜクラスを分けるのか

アジャイル開発では、「計画に従うことよりも、変化に対応するすることを重視する」と宣言しています。

柔軟にユーザの変更要求に応えるために、経験あるプログラマーは変更に柔軟に対応するように設計された プログラムでなければならないことを知っています。それで、クラスをデザインパターンや原則に 従って必要なクラスに分割し、それらを使用してシナリオを実現します。しかし、経験のないプログラマーは そんなことは気にしません。
例えば、クリックされたボタンの色を反転させるプログラムの例を、「1.1 役割をクラスに分けない例」 に記述しました。この例ではクリックされて呼び出さるメソッドの中にボタンの色を変更するシナリオ の全てを書いています。 他方、「1.2 役割をクラスに分けた例」は、変更に耐えるように役割を考慮して設計されたクラス群を 使用してシナリオを実現しています。

では、どのように変更に柔軟に対応可能でしょうか。色の反転を黒と赤から黒と緑に変更する場合、 クラスに役割を持たせたコードは変更の必要がないのが分かるでしょう。この場合の変更は Buttonの表示の役割を持ったクラスのメソッドを変えるだけです。

1.1 役割をクラスに分けない例

    public void processMouseEvent(MouseEvent me){
        int x = me.getX();
        int y = me.getY();
        int eventId = me.getID();

        switch(eventId){
            case MouseEvent.MOUSE_CLICKED:
                // Button #1の領域をチェック
                if(BUTTON_1_X < x && x < (BUTTON_1_X + BUTTON_WIDTH)
                        && BUTTON_1_Y < y && y < (BUTTON_1_Y + BUTTON_HEIGHT)) {
                    // 色を反転
                    if (buttonColor1 == Color.black)    buttonColor1 = Color.red;
                    else                                buttonColor1 = Color.black;
                }
                // Button #2の領域をチェック
                if(BUTTON_2_X < x && x < (BUTTON_2_X + BUTTON_WIDTH)
                        && BUTTON_2_Y < y && y < (BUTTON_2_Y + BUTTON_HEIGHT)) {
                    // 色を反転
                    if (buttonColor2 == Color.black)    buttonColor2 = Color.red;
                    else                                buttonColor2 = Color.black;
                }

                repaint();
                break;
            default:
                break;
        }
    }
  

1.2 役割をクラスに分けた例

    public void processMouseEvent(MouseEvent me){
        int x = me.getX();
        int y = me.getY();
        int eventId = me.getID();

        switch(eventId){
            case MouseEvent.MOUSE_CLICKED:
                // Button #1の領域をチェックし、色を反転
                if (button1.isSelected(x, y))   button1.swapColor();
                // Button #2の領域をチェックし、色を反転
                if (button2.isSelected(x, y))   button2.swapColor();

                repaint();
                break;
            default:
                break;
        }
    }
  

2. どう分けるのか

継承を利用する方法:似たような特性のクラス群が必要とされ、親クラスがシンプルであるか 将来変更の可能性低いのであれば継承を用いるのが適しています。この方法では、子クラスは親クラスの影響を受るので 各クラスの独立性は低くなります。
委譲を利用する方法:汎用的なライブラリを個々のクラスには似たところが無くても、共通のインターフェース を提供可能です。この方法では、クラス群の中にある他のクラスへの依存度が低いので個々のクラスの独立性は高くなります。

継承か委譲かを決め、プログラム設計を下記のデザイン・パターンや原則に基づいて行いました。
図1-1:クラス図

参考文献:Agile Software Development by Robert C Martin