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 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 メソッドの変更
タイプ:
進化タイプ:
前提: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 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 の追加
タイプ:
進化タイプ:
前提:
構成要素:
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