Java におけるコード進化パターン (Code Evolution Patterns in Java) - デザインパターン
asato shimotaki <asatohan at gmail.com>
最終更新日 : 2008/10/24 (2008/8/2 本ページから分割)
GoF デザインパターン関連
Decorator パターン関連
フィルタから Decorator パターン
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 の導入
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 の導入
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 の導入
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 階層がある
構成要素:
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 の導入
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
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 の追加
タイプ:
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 の追加によるクラス階層の形成
タイプ:
進化タイプ:
前提: ConcreteClass の候補となるクラスが一つ以上存在する。
構成要素:
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 の導入
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 Listafter:commands = new ArrayList (); public void addCommand(Command command) { commands.add(command); } public void executeCommands() { // 別に何でもいい for(Command command : commands) { command.execute(); } commands.clear(); } }
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 Listcommands = 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 メソッドの変更
タイプ:
進化タイプ:
前提:Command パターンが適用された構造がある。
構成要素:
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 Listcommands = 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 Listcommands = 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 の追加
タイプ:
進化タイプ:
前提:
構成要素:
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