[ホームへ戻る] [前へ] [上へ] [次へ]

デザインパターンを読み解く

デザインパターンとは


GoF23使使





 サイト
  GOFのパターンについて
  JavaでHelloWorld デザインパターン
  デザインパターン
  Java言語で学ぶデザインパターン入門
  デザインパターンの骸骨たち
  Javaプログラマのためのデザインパターン入門

 書籍

  『オブジェクト指向における再利用のためのデザインパターン』
  『Java言語で学ぶデザインパターン入門』
  『Java言語で学ぶデザインパターン入門 マルチスレッド編』
  『オブジェクト脳のつくり方―Java・UML・EJBをマスターするための究極の基礎講座    Be Agile!』
  『Javaデザインパターン徹底攻略    標準プログラマーズライブラリ』
  『独習デザインパターン』


23

GoF2323





・上位コンセプト(あまりにも用途が具体的過ぎる)
Strategy
Command
State
Interpreter

・上位コンセプト(クラス構成の方法であってテクニックではない。自然に使うもの)
Factory Method
Abstract Factory
Builder
Proxy
Facade
Memento
Prototype
Template
Mediator
Observer
Bridge

・テクニック(役立つものもあるが、あまり使わないものもある)
Singleton
FlyWeight
Adaptor
Composite
Iterator
Visitor
Decorator
ChainOfResponsibility

23SingletonFlyweight

使StrategyStateGoF


23
  目的
生成 構造 振る舞い
範囲 クラス Factory Method AdapterInterpreter
Template
オブジェクト Abstract Factory
Builder
Prototype
Singleton
Adapter
Bridge
Composite
Decorator
Facade
Flyweight
Proxy
Chain of Responsibility
Command
Iterator
Mediator
Memento
Observer
State
Strategy
Visitor

■私の分類

・ポリモーフィズム(サブクラスによる切り替え)
Template
Factory Method
Strategy
Command
State
Bridge
Composite
Interpreter
ChainOfResponsibility

・仲介
Abstract Factory
Builder
Facade
Mediator

・Wrapper
Adapter
Proxy
Decorator
Memento

・機能分散
Observer
Visitor
Iterator

・インスタンス共有
Singleton
FlyWeight
Prototype

<まとめ>

  ポリモーフィズム 生成 機能分散 仲介 Wrapper インスタンス保持
Template      
Factory Method     
Strategy      
Command      
State      
Composite      
Interpreter      
Bridge     
ChainOfResponsibility      
Abstract Factory   
Builder    
Facade     
Mediator     
Adaptor     
Proxy     
Decorator      
Memento     
Observer    
Visitor    
Iterator     
Singleton    
FlyWeight    
Prototype    


ポリモーフィズム(サブクラスによる切り替え、抽象化)


3使使使

使

調

Template


B
class Hogehoge {
    void doit() {
         ... 処理A ...

         ... 処理B ...

         ... 処理C ...
    }
}




1if

2





1
    void doit() {
         ... 処理A ...

         if (hoge == 1) {
             ... 処理B ...
         }
         else {
             ... 処理B' ...
         }

         ... 処理C ...
    }

ifelse if


2B
    void doit() {
         ... 処理A ...

         execute();

         ... 処理C ...
    }

    void abstract execute();




    void execute() {
        init();
        inputCheck();
        execMain();
    }
    void abstract init();
    void abstract inputCheck();
    void abstract execMain();


Factory Method


Abstract FactoryFactoryTemplate
class Hogehoge {
    void doit() {
         List list = new Vector();

         list.add(foo);
         ....
    }
}

Vector使
abstract class Hogehoge {
    void doit() {
         List list = create();

         list.add(foo);
         ....
    }
    abstract List create();
}

class HogeAList extends Hogehoge {
    List create() {
        return new ArrayList();
    }
}

StrategyStateCommand使

Strategy


使使

State



Command


使

2undoredo

Bridge


WindowsUNIX


AB2A4B3使1 + 4 × 3  13Bridge使2 (4+3) = 9



2

Composite


使

Composite使使Composite使

Interpreter


Interpreter

htmlxmlSQLXSLT

InterpreterComposite

CompositeInterpreter便

config
config
property.1=aaa

category1 (
  property.2=zzz
  category2 (
   property.1=bbb
   property.2=123
  )
)

category3 (
 property.2=ccc
 property.3=456
)


class Config {
  Category[] category;
  Property[] property;
}

class Category {
  String name;
  Category[] category;
  Property[] property;
}

CategoryCategoryCategoryPropertyCompositeInterpreter




3 - 5 + 6 * 5 * (6 - 5)

-×

×





Interpreter使getValue()
interface Node {
  abstract int getValue();
}

class PlusOperand implements Node {
  Node[] node;
  int getValue() {
    int value = 0;
    for (int i=0;i < node.length;i++) {
      value += node[i].getValue();
    }
    return value;
  }
}

class Operand implements Node {
  int value;
  int getValue() {
    return value;
  }
}

なお、Interpreterはパースのときに使われるパターンではないので、テキストから構文木を作るパース作業は別途行う必要があります。

以上、いくつかのパターンを列挙してきましたが、実際に適用する上で必要な知識は、ポリモーフィズムを使う、というただそれだけのことです。何が切り替えの対象になるかは、その状況状況によって違ってきます。

そのほかのパターンでもポリモーフィズムによる切り替えを基礎にしているパターンは多くありますが、ここに挙げたのはそれが要のものです。

Chain of Responsibility

このパターンもサブクラスによる処理の切り替えですが、処理するかどうかをサブクラス自身に判断させているところと、複数のサブクラスに対して順に処理を依頼しているところが、これまでのものと異なっています。

非ポリモーフィックな書き方をすれば、使用するサブクラスの切り替えは以下のようにif-else文かswitch文かを使って行います。

Handler hdr;

switch (cnt) {
case 0:
    hdr = new AbcHandler();
case 2:
    hdr = new XyzHandler();
default:
    hdr = new DefHandler();
}

hdr.handle();

switchifswitch

Chain Of Responsibilityswitch
class AbcHandler extends Handler {
    boolean handle(int cnt) {
        if (cnt != 0) {
            return false;
        }
        else {
            ... 処理 ...
            return true;
        }
    }
}



11




Handler




使JavaAwt使












Manager

Abstract Factory


FactoryFactory MethodFactoryFactory MethodnewAbstract Factory

createnewFactory Method

Factory

Abstract FactoryBuilder

Builder


Abstract FactoryBuildernew1

BuilderBuilderDirectorBuilderDirectorBuilderBuilderDirectorBuilderDirector使

Builder1

Builder使

Maker

Facade





. 11


2Abstract FactoryBuilderFacade


jar


使Manager

Facade

Mediator


Mediator

ObserverObserverMediatorObserverMediator1

FacadeMediator調

Wrapper


WrapperWrapper1


Adapter





3


1. 

使getAdp()getA()AdaptergetA()getAdp()


2. 

JavaListenerimplementAdapter


3. protected使

publicpublic
public class A {
    protected void exec() {
        ... 処理 ...
    }
}

public class B extends A {
    public void execA() {
        super.exec();
    }
}

Proxy


ProxyProxy

Decorator


使Wrap

WrapWrapDecorate

Java
public abstract class Border extends Display {
    protected Display display;
    protected Border(Display display) {
        this.display = display;
    }
    public String getRowText(int row) {
        return borderChar + display.getRowText(row) + borderChar;
    }
}


使


使使使


protected使

Java使

使使

Memento











使


public使




jarjar

Iterator




Iterator

IteratorIteratorIterator

Observer


Observer




ListenerHandler

Visitor


this使


accept()Visitoraccept()Visitorvisit()Visitor

visit()accpetvisit()accept()Visitor


VisitorVisitor使

Visitorvisit()visit()

CompositeVisitorvisit()visit()Visitorif使accept()accept()visitor.visit(this);



CompositeVisitoraccept()Java
Compositeパターンのみ場合 ――VisitorなしにEntry自身が処理を行う

public class File extends Entry {
    // ... 中略 ...
    protected void printList(String prefix) {
        System.out.println(prefix + "/" + this);
    }
}

public class Directory extends Entry {
    // ... 中略 ...
    protected void printList(String prefix) {
        System.out.println(prefix + "/" + this);
        Iterator it = directory.iterator();
        while (it.hasNext()) {
            Entry entry = (Entry)it.next();
            entry.printList(prefix + "/" + name); //ポリモーフィズム
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Directory rootdir = new Directory("root");
        // ... 中略 ...
        rootdir.printList();
    }
}

accept()なしの場合 ――VisitorがEntryの処理を行う

public class ListVisitor extends Visitor {
    private String currentdir = "";
    public void visit(File file) {
        System.out.println(currentdir + "/" + file);
    }
    public void visit(Directory directory) {
        System.out.println(currentdir + "/" + directory);
        String savedir = currentdir;
        currentdir = currentdir + "/" + directory.getName();
        Iterator it = directory.iterator();
        while (it.hasNext()) {
            Entry entry = (Entry)it.next();
            if (entry instanceof File) { //非ポリモーフィズム
                visit((File)entry);
            }
            else if (entry instanceof Directory) {
                visit((Directory)entry);
            }
        }
        currentdir = savedir;
    }
}

public class Main {
    public static void main(String[] args) {
        Directory rootdir = new Directory("root");
        // ... 中略 ...
        ListVisitor lv = new ListVisitor();
        lv.visit(rootdir);
    }
}


accept()ありの場合――EntryがVisitorを訪問させる

public class ListVisitor extends Visitor {
    private String currentdir = "";
    public void visit(File file) {
        System.out.println(currentdir + "/" + file);
    }
    public void visit(Directory directory) {
        System.out.println(currentdir + "/" + directory);
        String savedir = currentdir;
        currentdir = currentdir + "/" + directory.getName();
        Iterator it = directory.iterator();
        while (it.hasNext()) {
            Entry entry = (Entry)it.next();
            entry.accept(this); // ポリモーフィズム
        }
        currentdir = savedir;
    }
}

public class Directory extends Entry {
    // ... 中略 ...
    public void accept(Visitor v) {
        v.visit(this);
    }
}

public class Main {
    public static void main(String[] args) {
        Directory rootdir = new Directory("root");
        // ... 中略 ...
        rootdir.accept(new ListVisitor());
    }
}


Visitor

http://java-house.jp/ml/archive/j-h-b/014912.html

obj1, obj2, arg1, arg2 

1. obj1.do(obj2, arg1, arg2)

2. obj2.do(obj1, arg1, arg2)

(obj1, obj2).do(arg1, arg2)java使Visitor


Visitoraccept()instanceof使
http://www.ncfreak.com/asato/doc/patterns/visitor.html


使

Singleton


1使使

Singleton使privatestatic使1static使Singleton使staticSingleton

http://www.freeml.com/message/patterns@freeml.com/0001069


使使Stack

Singletonsynchronizeddouble-checked locking

dW Java technology double-checked lockingSingleton

static

FlyWeight


使Singleton使使

使IDMap使

Prototype


使FlyWeightPrototype

javaclone()deepshallow

Prototype
サブクラスによって分ける場合

abstract class Animal {
  abstract int getLeg();
}
class Kame extends Animal {
  int getLeg() {
    return 4;
  }
}
class Tsuru extends Animal {
  int getLeg() {
    return 2;
  }
}

インスタンスによって分ける場合

class Animal {
  String type;
  Animal(String type) {
    this.type = type;
  }
  int getLeg() {
    if (type.equals("Kame")) {
      return 4;
    }
    else if (type.equals("Tsuru")) {
      return 2;
    }
  }
}

使


沿Java使

沿






使使使


DecoratorChainOfResponsibility使使





この内容についてご意見をください

 
   役に立った    まあまあ    つまらない    難しい    疑問がある

コメント(質問・指摘・要望なんでもどうぞ)
  
メールアドレス: 

  

Copyright Dayan All rights reserved. Create: 2004.08.31 Last Update: 2006.10.10