home > デザインパターン >

ForNext

Only Do What Only You Can Do

Strategy

VBScript

JScript

Perl

PHP

Python

Ruby

PowerShell

Scala

F#

C

C++

C++Builder

VC++

C#

Java

更新日 : 2010.11.22

■ Step1
Duckクラスから派生したMallardDuck, RedHeadDuckクラスを作成し、 MiniDuckSimulatorから操作する

■ Duck
public abstract class Duck {
    public Duck() {
    }

    abstract void display();

    public void performFly() {
        System.out.println("I'm flying!!");
    }

    public void performQuack() {
        System.out.println("Quack");
    }
}
■ MallardDuck
public class MallardDuck extends Duck {

    public MallardDuck() {
    }

    public void display() {
        System.out.println("I'm a real Mallard duck");
    }
}
■ RedHeadDuck
public class RedHeadDuck extends Duck {

    public RedHeadDuck() {
    }

    public void display() {
        System.out.println("I'm a real Red Headed duck");
    }
}
■ MiniDuckSimulator
public class MiniDuckSimulator {
    public static void main(String[] args) {
        MallardDuck mallard = new MallardDuck();
        RedHeadDuck redhead = new RedHeadDuck();

        mallard.display();
        mallard.performQuack();
        mallard.performFly(); 

        System.out.println();

        redhead.display();
        redhead.performQuack();
        redhead.performFly(); 
    }
}
I'm a real Mallard duck
Quack
I'm flying!!

I'm a real Red Headed duck
Quack
I'm flying!!

■ Step2
Duckクラスから派生したRubberDuck, DecoyDuckクラスを追加する。 既存のクラスとは、動作が異なるので オーバーライドする。

■ RubberDuck (追加)
public class RubberDuck extends Duck {

    public RubberDuck() {
    }

    public void display() {
        System.out.println("I'm a rubber duckie");
    }

    // オーバーライド
    public void performFly() {
        System.out.println("I can't fly");
    }

    // オーバーライド
    public void performQuack() {
        System.out.println("Squeak");
    }
}
■ DecoyDuck (追加)
public class DecoyDuck extends Duck {

    public DecoyDuck() {
    }

    public void display() {
        System.out.println("I'm a duck Decoy");
    }

    // オーバーライド
    public void performFly() {
        System.out.println("I can't fly");
    }

    // オーバーライド
    public void performQuack() {
        System.out.println("<< Silence >>");
    }
}
■ MiniDuckSimulator (変更)
public class MiniDuckSimulator {
    public static void main(String[] args) {
        MallardDuck mallard = new MallardDuck();
        RedHeadDuck redhead = new RedHeadDuck();
        RubberDuck  rubber  = new RubberDuck(); // 追加
        DecoyDuck   decoy   = new DecoyDuck();  // 追加

        mallard.display();
        mallard.performQuack();
        mallard.performFly(); 

        System.out.println();

        redhead.display();
        redhead.performQuack();
        redhead.performFly(); 

        System.out.println();

        // 追加
        rubber.display();
        rubber.performQuack();
        rubber.performFly(); 

        System.out.println();

        // 追加
        decoy.display();
        decoy.performQuack();
        decoy.performFly(); 
    }
}
I'm a real Mallard duck
Quack
I'm flying!!

I'm a real Red Headed duck
Quack
I'm flying!!

I'm a rubber duckie
Squeak
I can't fly

I'm a duck Decoy
<< Silence >>
I can't fly

■ Step3
performQuack, performFly は、継承ではなく、委譲を使う。

■ FlyBehavior (追加)
public interface FlyBehavior {
    public void Fly();
}

public class FlyWithWings implements FlyBehavior {
    public void Fly() {
        System.out.println("I'm flying!!");
    }
}

public class FlyNoWay implements FlyBehavior {
    public void Fly() {
        System.out.println("I can't fly");
    }
}
■ QuackBehavior (追加)
public interface QuackBehavior {
    public void Quack();
}

public class Quack implements QuackBehavior {
    public void Quack() {
        System.out.println("Quack");
    }
}

public class Squeak implements QuackBehavior {
    public void Quack() {
        System.out.println("Squeak");
    }
}

public class MuteQuack implements QuackBehavior {
    public void Quack() {
        System.out.println("<< Silence >>");
    }
}
■ Duck (変更)
public abstract class Duck {
    // 追加
    FlyBehavior   flyBehavior;
    QuackBehavior quackBehavior;

    public Duck() {
    }

    abstract void display();

    public void performFly() {
        // 変更
        flyBehavior.Fly();
    }

    public void performQuack() {
        // 変更
        quackBehavior.Quack();
    }
}
■ MallardDuck (変更)
public class MallardDuck extends Duck {

    public MallardDuck() {
        // 追加
        flyBehavior   = new FlyWithWings();
        quackBehavior = new Quack();
    }

    public void display() {
        System.out.println("I'm a real Mallard duck");
    }
}
■ RedHeadDuck (変更)
public class RedHeadDuck extends Duck {

    public RedHeadDuck() {
        // 追加
        flyBehavior   = new FlyWithWings();
        quackBehavior = new Quack();
    }

    public void display() {
        System.out.println("I'm a real Red Headed duck");
    }
}
■ RubberDuck (変更)
public class RubberDuck extends Duck {

    public RubberDuck() {
        // 追加
        flyBehavior   = new FlyNoWay();
        quackBehavior = new Squeak();
    }

    public void display() {
        System.out.println("I'm a rubber duckie");
    }
}
■ DecoyDuck (変更)
public class DecoyDuck extends Duck {

    public DecoyDuck() {
        // 追加
        flyBehavior   = new FlyNoWay();
        quackBehavior = new MuteQuack();
    }

    public void display() {
        System.out.println("I'm a duck Decoy");
    }
}
I'm a real Mallard duck
Quack
I'm flying!!

I'm a real Red Headed duck
Quack
I'm flying!!

I'm a rubber duckie
Squeak
I can't fly

I'm a duck Decoy
<< Silence >>
I can't fly

■ Step4 Strategy パターン
実行中にオブジェクトの動作を変更する。

■ Duck (変更)
public abstract class Duck {
    FlyBehavior   flyBehavior;
    QuackBehavior quackBehavior;

    public Duck() {
    }

    // 追加 (実行中にオブジェクトの動作を変更)
    public void setFlyBehavior (FlyBehavior fb) {
        flyBehavior = fb;
    }

    // 追加 (実行中にオブジェクトの動作を変更)
    public void setQuackBehavior(QuackBehavior qb) {
        quackBehavior = qb;
    }

    abstract void display();

    public void performFly() {
        flyBehavior.Fly();
    }

    public void performQuack() {
        quackBehavior.Quack();
    }
}
■ FlyRocketPowered (追加)
public class FlyRocketPowered implements FlyBehavior {
    public void Fly() {
        System.out.println("I'm flying with a rocket");
    }
}
■ MiniDuckSimulator (変更)
public class MiniDuckSimulator {
    public static void main(String[] args) {
        Duck mallard = new MallardDuck();
        Duck redhead = new RedHeadDuck();
        Duck rubber  = new RubberDuck();
        Duck decoy   = new DecoyDuck();

        mallard.display();
        mallard.performQuack();
        mallard.performFly(); 

        System.out.println();

        redhead.display();
        redhead.performQuack();
        redhead.performFly(); 

        System.out.println();

        rubber.display();
        rubber.performQuack();
        rubber.performFly(); 

        System.out.println();

        decoy.display();
        decoy.performQuack();
        decoy.performFly(); 

        // 追加 (実行中にオブジェクトの動作を変更)
        decoy.setFlyBehavior(new FlyRocketPowered());
        decoy.performFly(); 
    }
}
I'm a real Mallard duck
Quack
I'm flying!!

I'm a real Red Headed duck
Quack
I'm flying!!

I'm a rubber duckie
Squeak
I can't fly

I'm a duck Decoy
<< Silence >>
I can't fly
I'm flying with a rocket

「社長命令起立」でオブジェクト指向を理解した気になっていたが...

Objective-C

D

VB

VB.NET

Delphi

Ada

PL/SQL

T-SQL

関数型

inserted by FC2 system