Java におけるコード進化パターン (Code Evolution Patterns in Java) - デザインパターン

asato shimotaki <asatohan at gmail.com>

最終更新日 : 2008/10/24 (2008/8/2 本ページから分割)

GoF デザインパターン関連

Decorator パターン関連

フィルタから Decorator パターン

before:

public class DirectoryExcluder implements FileFilter {

	public boolean accept(File pathname) {
		return pathname.isFile();
	}
}
public class Main {

	public static void main(String[] args) {

		File dir = new File("testdir");
		
		FileFilter filter = new DirectoryExcluder();
		
		File[] files = dir.listFiles(filter);
		for(int i = 0 ; i < files.length; i++) {
			System.out.println(files[i].getName());
		}
	}
}
after:

public class DirectoryExcluder implements FileFilter {

	public boolean accept(File pathname) {
		return pathname.isFile();
	}
}
public class JavaFileExcluder implements FileFilter {

	private FileFilter filter;

	public JavaFileExcluder(FileFilter filter) {
		this.filter = filter;
	}

	public boolean accept(File pathname) {
		return pathname.getName().endsWith(".java") == false && filter.accept(pathname);
	}
}
public class Main {

	public static void main(String[] args) {

		File dir = new File("testdir");
		
		FileFilter filter = new DirectoryExcluder();
		
		filter = new JavaFileExcluder(filter);
		
		File[] files = dir.listFiles(filter);
		for(int i = 0 ; i < files.length; i++) {
			System.out.println(files[i].getName());
		}
	}
}

Visitor パターン関連

Visitor の導入

before:
public interface Element {  }
public class ConcreteElementA implements Element { }
public class ConcreteElementB implements Element { }
after:

public interface Visitor {

	public void visit(ConcreteElementA elementA);
	public void visit(ConcreteElementB elementB);
}
public class ConcreteVisitorA implements Visitor {

	public void visit(ConcreteElementA elementA) { }
	public void visit(ConcreteElementB elementB) { }
}
public class ConcreteVisitorB implements Visitor {

	public void visit(ConcreteElementA elementA) { }
	public void visit(ConcreteElementB elementB) { }
}
public interface Element {

	public void accept(Visitor visitor);
}
public class ConcreteElementA implements Element {

	public void accept(Visitor visitor) {
		visitor.visit(this);
	}
}
public class ConcreteElementB implements Element {

	public void accept(Visitor visitor) {
		visitor.visit(this);
	}
}

ConcreteElement の導入

before:
public interface Visitor {

	public void visit(ConcreteElementA elementA);
	public void visit(ConcreteElementB elementB);
}
public class ConcreteVisitorA implements Visitor {

	public void visit(ConcreteElementA elementA) { }
	public void visit(ConcreteElementB elementB) { }
}
public class ConcreteVisitorB implements Visitor {

	public void visit(ConcreteElementA elementA) { }
	public void visit(ConcreteElementB elementB) { }
}
public interface Element {

	public void accept(Visitor visitor);
}
public class ConcreteElementA implements Element {

	public void accept(Visitor visitor) {
		visitor.visit(this);
	}
}
public class ConcreteElementB implements Element {

	public void accept(Visitor visitor) {
		visitor.visit(this);
	}
}
after:
public interface Visitor {

	public void visit(ConcreteElementA elementA);
	public void visit(ConcreteElementB elementB);
	public void visit(ConcreteElementC elementC);
}
public class ConcreteVisitorA implements Visitor {

	public void visit(ConcreteElementA elementA) { }
	public void visit(ConcreteElementB elementB) { }
	public void visit(ConcreteElementC elementC) { }
}
public class ConcreteVisitorB implements Visitor {

	public void visit(ConcreteElementA elementA) { }
	public void visit(ConcreteElementB elementB) { }
	public void visit(ConcreteElementC elementC) { }
}
public interface Element {

	public void accept(Visitor visitor);
}
public class ConcreteElementA implements Element {

	public void accept(Visitor visitor) {
		visitor.visit(this);
	}
}
public class ConcreteElementB implements Element {

	public void accept(Visitor visitor) {
		visitor.visit(this);
	}
}
public class ConcreteElementC implements Element {

	public void accept(Visitor visitor) {
		visitor.visit(this);
	}
}

進化パスと関連パターン

Factory パターン関連

Factory の導入

before:

after:

public interface Product { }
public class ConcreteProductA implements Product { }
public class ConcreteProductB implements Product { }
public class ConcreteProductC implements Product { }
public class ProductFactory {

	public static Product createProduct(int type) {
		
		if (type == 0) {
			return new ConcreteProductA();
		
		} else if (type == 1) {
			return new ConcreteProductB();
		
		} else {
			return new ConcreteProductC();
		}
	}
}

Concrete Factory の追加

状況&動機:

タイプ:

進化タイプ:

前提:Factory 階層がある

構成要素:

before:

public interface Product { }
public class ConcreteProductA implements Product {

}
public class ConcreteProductB implements Product {

}
public interface Factory {

	public Product createProduct();
}
public class ConcreteFactoryA implements Factory {

	@Override
	public ConcreteProductA createProduct() {
		return new ConcreteProductA();
	}
}
public class ConcreteFactoryB implements Factory {

	@Override
	public ConcreteProductB createProduct() {
		return new ConcreteProductB();
	}
}
after:

public interface Product { }
public class ConcreteProductA implements Product {

}
public class ConcreteProductB implements Product {

}
public class ConcreteProductC implements Product {

}
public interface Factory {

	public Product createProduct();
}
public class ConcreteFactoryA implements Factory {

	@Override
	public ConcreteProductA createProduct() {
		return new ConcreteProductA();
	}
}
public class ConcreteFactoryB implements Factory {

	@Override
	public ConcreteProductB createProduct() {
		return new ConcreteProductB();
	}
}

public class ConcreteFactoryC implements Factory {

	@Override
	public ConcreteProductC createProduct() {
		return new ConcreteProductC();
	}
}

進化リクエスタ/プロバイダ

議論

進化パス

パターン関係

関連パターン

参考文献とリソース

その他/疑問

Strategy パターン関連

Strategy の導入

before:

public class Context {

	public void contextInterface() {
		method();
	}
	
	private void method() { }
}
after:
public interface Strategy {

	public void algorithmInterface();
}

public class DefaultStrategy implements Strategy {

	public void algorithmInterface() { }
}
public class Context {

	private Strategy strategy = new DefaultStrategy();

	public void contextInterface() {

		strategy.algorithmInterface();
	}

	public void setStrategy(Strategy strategy) {
		this.strategy = strategy;
	}
}

Strategy の導入2

before:

public class Context {

	public void strategyA() {
		System.out.println("strategyA");
	}
	
	public void strategyB() {
		System.out.println("strategyB");
	}
	
	public void strategyC() {
		System.out.println("strategyC");
	}
}
public class Main {

	public static void main(String[] args) {

		Context context = new Context();

		context.strategyA();
		context.strategyB();
		context.strategyC();
	}
}
after:
public interface Strategy {
	public void execute();
}
public class Context {

	private List strategies = new ArrayList();

	public void addStrategy(Strategy strategy) {
		strategies.add(strategy);
	}
	
	public void executeStrategies() {
		for(Iterator itr = strategies.iterator(); itr.hasNext();) {
			Strategy strategy = (Strategy)itr.next();
			strategy.execute();
		}
	}

	public void strategyA() {
		System.out.println("strategyA");
	}
	
	public void strategyB() {
		System.out.println("strategyB");
	}
	
	public void strategyC() {
		System.out.println("strategyC");
	}
}

todo

Strategy の導入2 - Strategy 化

タイプ:リファクタリング?

before:

public interface Strategy {
	public void execute();
}
public class Context {

	private List strategies = new ArrayList();

	public void addStrategy(Strategy strategy) {
		strategies.add(strategy);
	}
	
	public void executeStrategies() {
		for(Iterator itr = strategies.iterator(); itr.hasNext();) {
			Strategy strategy = (Strategy)itr.next();
			strategy.execute();
		}
	}

	public void strategyA() {
		System.out.println("strategyA");
	}
	
	public void strategyB() {
		System.out.println("strategyB");
	}
	
	public void strategyC() {
		System.out.println("strategyC");
	}
}
public class Main {

	public static void main(String[] args) {

		Context context = new Context();

		context.strategyA();
		context.strategyB();
		context.strategyC();
	}
}
after:
public interface Strategy {
	public void execute();
}
public class ConcreteStrategyA implements Strategy {

	public void execute() {
		System.out.println("strategyA");
	}
}
public class ConcreteStrategyB implements Strategy {

	public void execute() {
		System.out.println("strategyB");
	}
}
public class ConcreteStrategyC implements Strategy {

	public void execute() {
		System.out.println("strategyC");
	}
}
public class Context {

	private List strategies = new ArrayList();

	public void addStrategy(Strategy strategy) {
		strategies.add(strategy);
	}
	
	public void executeStrategies() {
		for(Iterator itr = strategies.iterator(); itr.hasNext();) {
			Strategy strategy = (Strategy)itr.next();
			strategy.execute();
		}
	}
}
public class Main {

	public static void main(String[] args) {

		Context context = new Context();

		context.addStrategy( new ConcreteStrategyA() );
		context.addStrategy( new ConcreteStrategyB() );
		context.addStrategy( new ConcreteStrategyC() );
		
		context.executeStrategies();
	}
}

進化パス

関連パターン

参考文献とリソース

todo

Concrete Strategy の追加

状況&動機:

タイプ:

before:

public interface Strategy {
	public void algorithmInterface();
}
public class ConcreteStrategyA implements Strategy {
	
	public void algorithmInterface() {
		System.out.println("ConcreteStrategyA.algorithmInterface()");
	}
}
public class Context {

	private Strategy strategy;

	public void contextInterface() {
		strategy.algorithmInterface();
	}

	public void setStrategy(Strategy strategy) {
		this.strategy = strategy;
	}
}
after:
public interface Strategy {
	public void algorithmInterface();
}
public class ConcreteStrategyA implements Strategy {
	
	public void algorithmInterface() {
		System.out.println("ConcreteStrategyA.algorithmInterface()");
	}
}
public class ConcreteStrategyB implements Strategy {
	
	public void algorithmInterface() {
		System.out.println("ConcreteStrategyB.algorithmInterface()");
	}
}
public class Context {

	private Strategy strategy;

	public void contextInterface() {
		strategy.algorithmInterface();
	}

	public void setStrategy(Strategy strategy) {
		this.strategy = strategy;
	}
}

参考文献とリソース

進化パス

パターン関係

関連パターン

参考文献とリソース

todo

Strategy の導入3

状況&動機:

タイプ:

before:

public class Context {
	
	public void contextInterface() {
		System.out.println("process1");
		System.out.println("process2");
		System.out.println("process3");
	}
}
after:
public interface Strategy {
	public void algorithmInterface();
}
public class ConcreteStrategyA implements Strategy {

	public void algorithmInterface() {
		System.out.println("ConcreteStrategyA - process2");
	}
}
public class ConcreteStrategyB implements Strategy {

	public void algorithmInterface() {
		System.out.println("ConcreteStrategyB - process2");
	}
}
public class Context {
	
	private Strategy strategy = new ConcreteStrategyA();
	
	public void setStrategy(Strategy strategy) {
		this.strategy = strategy;
	}
	
	public void contextInterface() {
		System.out.println("process1");
		strategy.algorithmInterface();
		System.out.println("process3");
	}
}

参考文献とリソース

進化パス

パターン関係

関連パターン

参考文献とリソース

todo

set strategy method の追加

状況&動機:Strategy パターンを導入しようとしており、strategy オブジェクトを受け取るためのメソッドをクラスに追加する必要がある。

タイプ:

before:

public class Context {
	
	public void contextInterface() {
		System.out.println("Context.contextInterface()");
	}
}
after:
public interface Strategy {

	public void algorithmInterface();
}
public class ConcreteStrategyA implements Strategy {
	
	public void algorithmInterface() {
		System.out.println("ConcreteStrategyA.algorithmInterface()");
	}
}
public class ConcreteStrategyB implements Strategy {
	
	public void algorithmInterface() {
		System.out.println("ConcreteStrategyB.algorithmInterface()");
	}
}
public class Context {
	
	private Strategy strategy;

	public void setStrategy(Strategy strategy) {
		this.strategy = strategy;
	}
	
	public void contextInterface() {
		strategy.algorithmInterface();
	}
}

参考文献とリソース

進化パス

パターン関係

関連パターン

参考文献とリソース

todo

Template Method パターン関連

Template Method 導入のための AbstractClass の追加によるクラス階層の形成

状況&動機:Template Method 導入のために AbstractClass を追加し、ConcreteClass のロールを持つクラスとの間に継承関係を形成する。

タイプ:

進化タイプ:

前提: ConcreteClass の候補となるクラスが一つ以上存在する。

構成要素:

before:

public class ClassA { // ConcreteClass 候補

	public void methodA() { // template method メソッド候補
		System.out.println("before - methodA");
		methodB();
		System.out.println("after  - methodA");
	}
	private void methodB() { // primitive operation メソッド候補
		System.out.println("ClassA.methodB()");
	}
}
public class ClassB { // ConcreteClass 候補

	public void methodA() { // template method メソッド候補
		System.out.println("before - methodA");
		methodB();
		System.out.println("after  - methodA");
	}
	private void methodB() { // primitive operation メソッド候補
		System.out.println("ClassB.methodB()");
	}
}
after:

public abstract class AbstractClass { // AbstractClass ロール
}
public class ClassA extends AbstractClass { // ConcreteClass ロール

	public void methodA() {
		System.out.println("before - methodA");
		methodB();
		System.out.println("after  - methodA");
	}
	private void methodB() {
		System.out.println("ClassA.methodB()");
	}
}
public class ClassB extends AbstractClass { // ConcreteClass ロール

	public void methodA() {
		System.out.println("before - methodA");
		methodB();
		System.out.println("after  - methodA");
	}
	private void methodB() {
		System.out.println("ClassB.methodB()");
	}
}

進化リクエスタ/プロバイダ

議論

進化パス

パターン関係

関連パターン

参考文献とリソース

その他/疑問

Template Method の導入

before:

public class Item { // 直接は関係なし
	
	private String name;
	private int price;
	
	public Item(String name, int price) {
		this.name  = name;
		this.price = price;
	}
	
	public String getName() {
		return name;
	}
	public int getPrice() {
		return price;
	}
}
public class TextBasedItemOutputter {
	
	public void output(Item[] items) {
		
		for(int i = 0 ; i < items.length; i++) {

			String name = items[i].getName();
			int price   = items[i].getPrice();

			System.out.println("name = " + name + ", price = " + price);
		}
	}
}
after:
public class Item { // 直接は関係なし。変更なし。
	
	private String name;
	private int price;
	
	public Item(String name, int price) {
		this.name  = name;
		this.price = price;
	}
	
	public String getName() {
		return name;
	}
	public int getPrice() {
		return price;
	}
}
public abstract class AbstractItemOutputter {

	public void output(Item[] items) {
	
		for(int i = 0 ; i < items.length; i++) {
			output(items[i]);
		}
	}
	
	protected abstract void output(Item item);
}
public class TextBasedItemOutputter extends AbstractItemOutputter {
	
	protected void output(Item item) {

		String name = item.getName();
		int price   = item.getPrice();

		System.out.println("name = " + name + ", price = " + price);
	}
}

public class XmlBasedItemOutputter extends AbstractItemOutputter {

	protected void output(Item item) {

		String nameElm  = "" +  item.getName()  + "";
		String priceElm = "" + item.getPrice() + "";

		System.out.println("" + nameElm + priceElm + "");
	}
}

進化パス

関連パターン

参考文献とリソース

todo

抽象クラスの Template Method 化

状況&動機:

タイプ:リファクタリング

進化タイプ:

前提:抽象クラスとそのクラスのサブクラスが存在する。

before:

public abstract class AbstractClass {

	public void method() {
		System.out.println("AbstractClass.method()");
	}
	
	public abstract void abstractMethod(); // 単なる抽象メソッド。AbstractClass が抽象クラスであることを表すために定義。進化の観点からは関係なし。
}
public class ConcreteClass extends AbstractClass {

	@Override
	public void method() {

		super.method(); // ここが重要。
	
		System.out.println("ConcreteClass.method()");
	}
	
	@Override
	public void abstractMethod() {
		System.out.println("ConcreteClass.abstractMethod()");
	}
}
after:

public abstract class AbstractClass { // AbstractClass のロール
	
	public void method() { // templateMethod のロール

		System.out.println("AbstractClass.method()");
	
		primitiveMethod();
	}
	
	protected void primitiveMethod() { } // primitiveOperation のロール。抽象メソッドでもよい。

	public abstract void abstractMethod();
}

public class ConcreteClass extends AbstractClass {

	@Override
	protected void primitiveMethod() { // method() はオーバーライドせずに、この primitiveMethod() をオーバーライドする。
		System.out.println("ConcreteClass.primitiveMethod()");
	}
	
	@Override
	public void abstractMethod() {
		System.out.println("ConcreteClass.abstractMethod()");
	}
}

参考文献とリソース

進化リクエスタ/プロバイダ

進化を要求するクラスには、次が考えられる: 要求に答えて進化するクラスには、次が考えられる:

議論

進化パス

パターン関係

関連パターン

参考文献とリソース

todo

hook operation の追加

状況&動機:

タイプ:

進化タイプ:

前提:

before:

public abstract class AbstractClass {
	
	public void templateMethod() {

		primitiveOperation1();
		
		hookOperation1();

		primitiveOperation2();

	}
	
	protected abstract void primitiveOperation1();
	
	protected abstract void primitiveOperation2();

	protected void hookOperation1()  { }
}
public class ConcreteClassA extends AbstractClass {
	
	@Override
	protected void primitiveOperation1() {
		System.out.println("ConcreteClassA.primitiveOperation1()");
	}
	@Override
	protected void primitiveOperation2() {
		System.out.println("ConcreteClassA.primitiveOperation2()");
	}
}
public class ConcreteClassB extends AbstractClass {
	
	@Override
	protected void primitiveOperation1() {
		System.out.println("ConcreteClassB.primitiveOperation1()");
	}
	
	@Override
	protected void primitiveOperation2() {
		System.out.println("ConcreteClassB.primitiveOperation2()");
	}
	
	@Override
	protected void hookOperation1() {
		System.out.println("ConcreteClassB.hookOperation1()");
	}
}
after:

public abstract class AbstractClass {
	
	public void templateMethod() {

		primitiveOperation1();
		
		hookOperation1();

		primitiveOperation2();

		hookOperation2();
	}
	
	protected abstract void primitiveOperation1();

	protected abstract void primitiveOperation2();

	protected void hookOperation1()  { }

	protected void hookOperation2()  { }
}
public class ConcreteClassA extends AbstractClass {
	
	@Override
	protected void primitiveOperation1() {
		System.out.println("ConcreteClassA.primitiveOperation1()");
	}
	@Override
	protected void primitiveOperation2() {
		System.out.println("ConcreteClassA.primitiveOperation2()");
	}
}

public class ConcreteClassB extends AbstractClass {
	
	@Override
	protected void primitiveOperation1() {
		System.out.println("ConcreteClassB.primitiveOperation1()");
	}
	
	@Override
	protected void primitiveOperation2() {
		System.out.println("ConcreteClassB.primitiveOperation2()");
	}
	
	@Override
	protected void hookOperation1() {
		System.out.println("ConcreteClassB.hookOperation1()");
	}
}
public class ConcreteClassC extends AbstractClass {
	
	@Override
	protected void primitiveOperation1() {
		System.out.println("ConcreteClassC.primitiveOperation1()");
	}
	
	@Override
	protected void primitiveOperation2() {
		System.out.println("ConcreteClassC.primitiveOperation2()");
	}
	
	@Override
	protected void hookOperation2() {
		System.out.println("ConcreteClassC.hookOperation2()");
	}
}

参考文献とリソース

進化リクエスタ/プロバイダ

議論

進化パス

パターン関係

関連パターン

参考文献とリソース

todo

Command パターン関連

Concrete Command の追加

状況&動機:

タイプ:

進化タイプ:

前提:

before:

public interface Command {

	public void execute();
}
public class ConcreteCommandA implements Command {
	
	public void execute() {
		System.out.println("ConcreteCommandA.execute()");
	}
}
public class ConcreteCommandB implements Command {
	
	public void execute() {
		System.out.println("ConcreteCommandB.execute()");
	}
}
public class CommandProcessor {

	private List commands = new ArrayList();

	public void addCommand(Command command) {
		commands.add(command);
	}
	
	public void executeCommands() { // 別に何でもいい

		for(Command command : commands) {
			command.execute();
		}
		commands.clear();
	}
}
after:

public interface Command {

	public void execute();
}
public class ConcreteCommandA implements Command {
	
	public void execute() {
		System.out.println("ConcreteCommandA.execute()");
	}
}
public class ConcreteCommandB implements Command {
	
	public void execute() {
		System.out.println("ConcreteCommandB.execute()");
	}
}
public class ConcreteCommandC implements Command {
	
	public void execute() {
		System.out.println("ConcreteCommandC.execute()");
	}
}

public class CommandProcessor {

	private List commands = new ArrayList();

	public void addCommand(Command command) {
		commands.add(command);
	}
	
	public void executeCommands() { // 別に何でもいい

		for(Command command : commands) {
			command.execute();
		}
		commands.clear();
	}
}

参考文献とリソース

進化リクエスタ/プロバイダ

議論

進化パス

パターン関係

関連パターン

参考文献とリソース

todo

Concrete Command の execute メソッドの変更

状況&動機:Concrete Command の exexute メソッドの変更が必要になった。

タイプ:

進化タイプ:

前提:Command パターンが適用された構造がある。

構成要素:

before:

public interface Command {
	public void execute();
}
public class ConcreteCommandA implements Command {

	@Override
	public void execute() {
		System.out.println("ConcreteCommandA.execute()");
	}
}
public class ConcreteCommandB implements Command {

	@Override
	public void execute() {
		System.out.println("ConcreteCommandB.execute()");
	}
}
public class Invoker {
	
	private List commands = new ArrayList();
	
	public void add(Command c) {
		commands.add(c);
	}
	
	public void executeCommands() { // 別に何でもいい

		for(Command c : commands) {
			c.execute();
		}
	}
}
public class Client {

	public static void main(String[] args) {
		
		Invoker invoker = new Invoker();

		invoker.add( new ConcreteCommandA() );
		invoker.add( new ConcreteCommandB() );
	
		invoker.executeCommands();
	}
}
after:

public interface Command { // 変更なし
	public void execute();
}
public class ConcreteCommandA implements Command {

	@Override
	public void execute() {
		System.out.println("ConcreteCommandA.execute()");
		System.out.println("***"); // 新たに追加
	}
}
public class ConcreteCommandB implements Command { // 変更なし

	@Override
	public void execute() {
		System.out.println("ConcreteCommandB.execute()");
	}
}
public class Invoker { // 変更なし
	
	private List commands = new ArrayList();
	
	public void add(Command c) {
		commands.add(c);
	}
	
	public void executeCommands() { // 別に何でもいい

		for(Command c : commands) {
			c.execute();
		}
	}
}
public class Client {

	public static void main(String[] args) {
		
		Invoker invoker = new Invoker();

		invoker.add( new ConcreteCommandA() );
		invoker.add( new ConcreteCommandB() );
	
		invoker.executeCommands();
	}
}

進化リクエスタ/プロバイダ

議論

進化パス

パターン関係

関連パターン

参考文献とリソース

その他/疑問

その他のデザインパターン関連

Null Object パターン関連

Null オブジェクトの追加

状況&動機:

タイプ:追加

前提:interface (抽象クラス)とその interface を実装するクラス階層ががすでに存在する。

before:

public interface Task {

	public void execute();
}
public class NormalTask implements Task {
	
	public void execute() {
		System.out.println("NormalTask.execute()");
	}
}
after:
public class NormalTask implements Task {
	
	public void execute() {
		System.out.println("NormalTask.execute()");
	}
}
public class NullTask implements Task {
	
	public void execute() { }
}
public class NormalTask implements Task {
	
	private Task beforeTask = new NullTask();
	private Task afterTask  = new NullTask();
	
	public void execute() {
		
		beforeTask.execute();
		
		System.out.println("NormalTask.execute()");

		afterTask.execute();
	}
	
	public void setBeforeTask(Task beforeTask) {
		this.beforeTask = beforeTask;
	}
	public void setAfterTask(Task afterTask) {
		this.afterTask = afterTask;
	}
}

参考文献とリソース

進化パス

パターン関係

関連パターン

参考文献とリソース

todo

クラス継承による Null Object の追加

状況&動機:

タイプ:

進化タイプ:

前提:

構成要素:

before:

public class Component {

	public void method() {
		System.out.println("Component.method()");
	}
}
after:

public class Component {

	public void method() {
		System.out.println("Component.method()");
	}
}
public class NullComponent extends Component {

	@Override
	public void method() {
		
	}
}

進化リクエスタ/プロバイダ

議論

進化パス

パターン関係

関連パターン

Composite Patterns 関連

デザインパターンが一つ以上適用された構造の進化。

Strategy - Strategy

状況&動機:

タイプ:

before:

public interface Strategy {
	public void algorithmInterface();
}
public class ConcreteStrategyA implements Strategy {

	public void algorithmInterface() {
		System.out.println("ConcreteStrategyA");
	}
}
public class ConcreteStrategyB implements Strategy {

	public void algorithmInterface() {
		System.out.println("ConcreteStrategyB - process1");
		System.out.println("ConcreteStrategyB - process2");
		System.out.println("ConcreteStrategyB - process3");
	}
}
after:
public interface Strategy2 {
	public void algorithmInterface();
}
public class ConcreteStrategy2A implements Strategy2 {
	public void algorithmInterface() {
		System.out.println("ConcreteStrategy2A - process2");
	}
}
public class ConcreteStrategy2B implements Strategy2 {
	public void algorithmInterface() {
		System.out.println("ConcreteStrategy2B - process2");
	}
}

public interface Strategy {
	public void algorithmInterface();
}
public class ConcreteStrategyA implements Strategy {

	public void algorithmInterface() {
		System.out.println("ConcreteStrategyA");
	}
}
public class ConcreteStrategyB implements Strategy {

	private Strategy2 strategy = new ConcreteStrategy2A();
	
	public void setStrategy2(Strategy2 strategy) {
		this.strategy = strategy;
	}

	public void algorithmInterface() {
		System.out.println("ConcreteStrategyB - process1");
		strategy.algorithmInterface();
		System.out.println("ConcreteStrategyB - process3");
	}
}

public class Context {
	
	private Strategy strategy = new ConcreteStrategyA();
	
	public void setStrategy(Strategy strategy) {
		this.strategy = strategy;
	}
	
	public void contextInterface() {
		System.out.println("process1");
		strategy.algorithmInterface();
		System.out.println("process3");
	}
}

参考文献とリソース

進化パス

パターン関係

関連パターン

参考文献とリソース

todo

Strategy - Strategy - concrete strategy の追加

状況&動機:

タイプ:

before:

public interface Strategy2 {
	public void algorithmInterface();
}
public class ConcreteStrategy2A implements Strategy2 {
	public void algorithmInterface() {
		System.out.println("ConcreteStrategy2A - process2");
	}
}
public class ConcreteStrategy2B implements Strategy2 {
	public void algorithmInterface() {
		System.out.println("ConcreteStrategy2B - process2");
	}
}

public interface Strategy {
	public void algorithmInterface();
}
public class ConcreteStrategyA implements Strategy {

	public void algorithmInterface() {
		System.out.println("ConcreteStrategyA");
	}
}
public class ConcreteStrategyB implements Strategy {

	private Strategy2 strategy = new ConcreteStrategy2A();
	
	public void setStrategy2(Strategy2 strategy) {
		this.strategy = strategy;
	}

	public void algorithmInterface() {
		System.out.println("ConcreteStrategyB - process1");
		strategy.algorithmInterface();
		System.out.println("ConcreteStrategyB - process3");
	}
}

public class Context {
	
	private Strategy strategy = new ConcreteStrategyA();
	
	public void setStrategy(Strategy strategy) {
		this.strategy = strategy;
	}
	
	public void contextInterface() {
		System.out.println("process1");
		strategy.algorithmInterface();
		System.out.println("process3");
	}
}
after:
public interface Strategy2 {
	public void algorithmInterface();
}
public class ConcreteStrategy2A implements Strategy2 {
	public void algorithmInterface() {
		System.out.println("ConcreteStrategy2A - process2");
	}
}
public class ConcreteStrategy2B implements Strategy2 {
	public void algorithmInterface() {
		System.out.println("ConcreteStrategy2B - process2");
	}
}
public class ConcreteStrategy2C implements Strategy2 {
	public void algorithmInterface() {
		System.out.println("ConcreteStrategy2C - process2");
	}
}
public interface Strategy {
	public void algorithmInterface();
}
public class ConcreteStrategyA implements Strategy {

	public void algorithmInterface() {
		System.out.println("ConcreteStrategyA");
	}
}
public class ConcreteStrategyB implements Strategy {

	private Strategy2 strategy = new ConcreteStrategy2A();
	
	public void setStrategy2(Strategy2 strategy) {
		this.strategy = strategy;
	}

	public void algorithmInterface() {
		System.out.println("ConcreteStrategyB - process1");
		strategy.algorithmInterface();
		System.out.println("ConcreteStrategyB - process3");
	}
}

public class Context {
	
	private Strategy strategy = new ConcreteStrategyA();
	
	public void setStrategy(Strategy strategy) {
		this.strategy = strategy;
	}
	
	public void contextInterface() {
		System.out.println("process1");
		strategy.algorithmInterface();
		System.out.println("process3");
	}
}

参考文献とリソース

進化パス

パターン関係

関連パターン

参考文献とリソース

todo

参考文献とリソース

リソース:

更新履歴

todo