デザインパターンUMLクラス図

パターンクラス図コレクション
Ver. 1.0 (1999/10/16)
このパターンクラス図コレクションは,ソフトバンク・パブリッシング社刊の月刊誌「Cマガジン」1999年4月号
から11月号まで著者(大城正典)が連載した「JavaとC++によるデザインパターン」の補足として作成したものです。
よく知られるようになったパターンをUML記法で記述しています。
【注意】
このパターンクラス図コレクションに収録されているパターンに関する説明は,「Cマガジン」の上記連載記事を
参照して下さい。誤字脱字など,お気づきの点がありましたら著者までe-mail([email protected])にてご連絡
下さると助かります。なお,このパターンクラス図コレクションに関するその他のご質問は,著者もCマガジン編集
部もお答え致しかねますので,ご了承下さい。
このパターンクラス図コレクションの著作権は,著作者の私(大城正典)に帰属します。個人的な学習のための複
製は許可しますが,ネットワーク,CD-ROMなどの記録メディアおよび印刷媒体を介しての登録・公開・複製を行う
ことは,これを固く禁止致します。
1999年10月16日 大城正典
基本構造
●Template Methodパターン
●Strategyパターン
●自己参照型パターン
・多重度0以上の自己参照
Compositeパターン,Interpreterパターン
・多重度1以下の自己参照
Decoratorパターン,Chain of Responsibi
lityパターン,Proxyパターン
Fig.1[Template Methodパターン]
Template Methodパターン
テンプレートメソッド
の中で各プリミティブ
操作を呼び出す
テンプレートメソッド
を定義する抽象クラス
利用者1
User1
利用者2
User2
※ finalとは,“サブクラスで
オーバライドされない”と
いう意味で使用しています。
{
…
primitiveOperation1();
…
primitiveOperation2();
…
}
AbstractClass
{abstract}
+ templateMethod() {final}
# primitiveOperation1()
# primitiveOperation2()
一般化層
特殊化層
ConcreteClass1
ConcreteClass2
ConcreteClass3
# primitiveOperation1()
# primitiveOperation2()
# primitiveOperation1()
# primitiveOperation2()
# primitiveOperation1()
# primitiveOperation2()
プリミティブ操作をオーバライドする具体クラス群
1
Copyright (C) 1999 by Masanori Ohshiro
Fig.2[Strategyパターン]
Strategyパターン
主たるクラス
User
1
《 interface 》
Strategy
Context
{
if( strategy != null )
strategy.algorithmInterface();
}
- strategy
+ contextInterface()
algorithmInterface()
一般化層
特殊化層
※ バリエーションを得たい操作をFig.5と同じように別の
クラスStrategyに委譲する。そして,Strategyをサブ
クラス化してバリエーション化する。
※ Contextオブジェクトに集約させるStrategyオブジェク
トを切り替えることで,Contextオブジェクトの振る舞
いを動的に変えることができる。
具体クラス群
{
独自の定義で
オーバライド
する;
}
ConcreteStrategy1
ConcreteStrategy2
+ algorithmInterface()
+ algorithmInterface()
Fig.3[Compositeパターン(透過性優先版)]
Compositeパターン(透過性優先版)
木構造をなす要素の
ための抽象クラス
利用者
*
Component
User
{ abstract }
{不正な呼出し}
+ operation()
+ add( c : Component )
+ remove( c : Component )
+ getChild() : Iterator
{不正な呼出し}
{不正な呼出し}
一般化層
特殊化層
具体クラス群
Leaf
+ operation()
子を持てないノード
のための具体クラス
Composite
- children
{
+ operation()
+ add( c : Component )
+ remove( c : Component )
+ getChild() : Iterator
子を持てるノードの
ための具体クラス
2
childrenに登録
されている全
子ノードに対し
operation()を呼
び出す
}
Copyright (C) 1999 by Masanori Ohshiro
Fig.4[Compositeパターン(安全性優先版)]
Compositeパターン(安全性優先版)
木構造をなす要素の
ための抽象クラス
利用者
*
Component
User
{ abstract }
{
return null;
+ getComposite() : Composite
}
+ operation()
一般化層
特殊化層
具体クラス群
Leaf
Composite
- children
+ operation()
{ return this; }
+ getComposite() : Composite
+ operation()
+ add( c : Component )
+ remove( c : Component )
+ getChild() : Iterator
子を持てないノード
のための具体クラス
子を持てるノードの
ための具体クラス
{
childrenに登録
されている全
子ノードに対し
operation()を呼
び出す
}
Fig.5[Interpreterパターン]
Interpreterパターン
利用者
User
構文木の要素(文法記号)
のための抽象クラス
*
AbstractExpression
{ abstract }
Context
+ interpret( c : Context )
一般化層
解釈に必要な
グローバル情報
特殊化層
具体クラス群
TerminalExpression
+ interpret( c : Context )
終端記号のための具体クラス
NonTerminalExpression
- children
+ interpret( c : Context )
非終端記号ための具体クラス
3
Copyright (C) 1999 by Masanori Ohshiro
Fig.6[Decoratorパターン]
Decoratorパターン
1
利用者
《 interface 》
Component
User
operation( )
一般化層
特殊化層
Decorator
ConcreteComponent
{ abstract }
{
+ operation()
修飾されるコンポー
ネントの具体クラス
if( component != null )
component.operation();
# component : Component
+ operation()
}
{
スーパークラスである
Decoratorのoperation()
を呼び出す前後に,付加
的な操作addedOperation()
を呼び出して装飾を行う
}
具体装飾クラス群
ConcreteDecoratorA
ConcreteDecoratorB
+ operation()
+ addedOperation()
- addedState
+ operation()
※構造的には多重度1の上方自己参照
Fig.7[Chain of Responsibilityパターン]
Chain of Responsibilityパターン
0..1
利用者
Handler
User
{ abstract }
# successor : Handler
{
if( successor != null )
successor.handleRequest();
+ handleRequest( )
}
一般化層
特殊化層
{
自クラスがメッセージ
handleRequest()に責任を持っ
ていないなら,Handlerクラ
スのhandleRequest()を呼び出
して転送を行う。責任を持
っているなら対応する処理
を行う(この場合,メッセー
ジの転送はそこで終了する)。
}
具体クラス群
ConcreteHandlerA
ConcreteHandlerB
+ handleRequest()
+ handleRequest()
※構造的には多重度1以下の単純な自己参照(非上方型)
4
Copyright (C) 1999 by Masanori Ohshiro
Fig.8[Proxyパターン]
Proxyパターン
(a)複数の代理オブジェクトを連鎖させる場合(多重度1の上方自己参照)
0..1
利用者
《 interface 》
Subject
User
request( )
一般化層
特殊化層
Proxy
RealSubject
+ request()
本物のオブジェクト
のクラス
{ abstract }
{
if( subject != null )
realSubject.request();
+ request()
}
{
具体代理クラス群
必要に応じてスーパーク
ラスであるProxyのrequest()
を呼び出す
}
# subject : Subject
ConcreteProxyA
+ request()
ConcreteProxyB
+ request()
(b)代理オブジェクトを1個に限定する場合(自己参照ではない)
利用者
《 interface 》
Subject
User
request( )
※ 構造的には,オブジェクトコ
ンポジションで,集約側と被
集約側に共通のスーパークラ
ス(Subject)がある形
一般化層
特殊化層
0..1
Proxy
RealSubject
+ request()
本物のオブジェクト
のクラス
必要に応じて
realRubject.request()
を呼び出す
# realSubject : Subject
+ request()
5
Copyright (C) 1999 by Masanori Ohshiro
オブジェクト生成パターン
●Factory Methodパターン
●コンポジション・パターン
Abstract Factoryパターン,Builderパターン,Prototypeパターン
●Singletonパターン
※ Singletonパターンのクラス図は用意していません
Fig.9[Factory Methodパターン]
Factory Methodパターン
利用者(=オブジェクト生成工場)
生成されるオブジェクト
Creator
《 interface 》
{ abstract }
Product
※ Creatorクラス内は,生成さ
れるオブジェクトの実際の型
には依存しないですむ
{
…
product = factoryMethod();
…
}
+ operation() {final}
# factoryMethod() : Product
生成側と生成されるものの間に,
パラレルなクラス階層が存在する
一般化層
特殊化層
具体クラス群
ConcreteProduct2
具体クラス群
ConcreteProduct1
ConcreteCreator1
ConcreteCreator2
# factoryMethod() : Product
# factoryMethod() : Product
生成
生成
Fig.10[Abstract Factoryパターン]
Abstract Factoryパターン
利用者
オブジェクト生成工場
《 interface 》
User
AbstractFactory
createProductA() : ProductA
生成されるオブジェクト
createProductB() : ProductB
《 interface 》
《 interface 》
ProductA
ProductB
パラレルなクラス階層
一般化層
特殊化層
具体クラス群
具体クラス群
具体クラス群
ConcreteProductA2
ConcreteProductA1
ConcreteProductB2
ConcreteProductB1
ConcreteFactory2
+ createProductA()
+ createProductB()
+ createProductA()
+ createProductB()
生成
生成
生成
ConcreteFactory1
生成
6
Copyright (C) 1999 by Masanori Ohshiro
Fig.11[Builderパターン]
Builderパターン
複合オブジェクト生成命令者
利用者
Director
User
# builder : Builder
生成される
オブジェクト
Builder
{ abstract }
+ construct() : Product
《 interface 》
+ buildPartKindB()
+ getResult():Product
{}
{}
一般化層
特殊化層
パラレルなクラス階層(Product側の
階層は無くてもよい場合もある)
具体クラス群
具体クラス群
ConcreteProduct2
空の
実装
+ buildPatrKindA()
…
builder.buildePartKindA();
…
builder.buildePartKindB();
…
return builder.getResult();
Product
オブジェクト
の生成工場
ConcreteProduct1
{ 独自の定義 }
{ return result; }
生成
ConcreteBuilder1
ConcreteBuilder2
- result : ConcreteProduct1
- result : ConcreteProduct2
+ buildPartKindA()
+ buildPartKindA()
+ buildPartKindB()
+ getResult() : Product
+ getResult() : Product
生成
Fig.12[Prototypeパターンの基本構造]
Prototypeパターンの基本構造
オブジェクト生成工場
兼
生産されるオブジェクト
利用者
User
# prototype : Prototype
+ operation() {final}
《 interface 》
Prototype
clone() : Prototype
{
…
product = prototype.clone();
…
}
一般化層
特殊化層
具体クラス群
自分のクローン
を生成して返す
ConcretePrototyp1
ConcretePrototype2
+ clone() : ConcretePrototype1
+ clone() : ConcretePrototype2
7
Copyright (C) 1999 by Masanori Ohshiro
インタフェイスを変更する媒介物
●Adaptorパターン
●Bridgeパターン
●Iteratorパターン
Fig.13[Adapterパターン(多重継承版)]
Adapterパターン(多重継承版)
※ Userは,Adapter1,2のオブジェ
クトをTargetのオブジェクトと
して扱う。Adapter1,2は,Adap
tee1,2のインタフェイス仕様を
Targetのインタフェイス仕様に
適合させている。
利用者
《 interface 》
Target
User
request()
一般化層
特殊化層
Adaptee1
Adaptee2
+ specialRequest1()
+ specialRequest2()
具体クラス群
{
specialReques1();
}
Adapter1
+ request()
Adapter2
{
specialRequest2();
}
+ request()
Fig.14[Adapterパターン(オブジェクトコンポジション版)]
Adapterパターン(オブジェクトコンポジション版)
利用者
《 interface 》
Target
User
request()
一般化層
特殊化層
具体クラス群
Adaptee1
+ specialRequest1()
Adaptee2
Adapter1
Adapter2
- adaptee1
- adaptee2
+ request()
+ request()
{
{
adaptee2.specialRequest2();
adaptee1.specialReques1();
}
+ specialRequest2()
}
8
Copyright (C) 1999 by Masanori Ohshiro
Fig.15[Bridgeパターン]
Bridgeパターン
インタフェイス階層と実装階層を橋渡しする“ブリッジ”
利用者
《 interface 》
Implementor
Abstraction
User
{ abstract }
{
…
if(imp != null) imp.operationImp();
…
}
- imp : Implementor
# operation1() {final}
# operation2() {final}
operationImp()
一般化層
特殊化層
具体クラス群
RefinedAbstractionA
RefinedAbstractionB
+ concreteOperationA()
+ concreteOperationB()
具体クラス群
ConcreteImplementor1
{
ConcreteImplementor2
{
… operation1(); …
… operation1(); operation2();…
}
}
インタフェイスのバリエーション化および
拡張を行う“インタフェイス階層”
+ operationImp()
+ operationImp()
実装のバリエーション化と拡張を行う“実装階層”
Fig.16[Iteratorパターン]
Iteratorパターン
コンテナ
生成されるイテレータ
利用者
《 interface 》
first()
next()
isDone()
currentItem()
《 interface 》
User
Iterator
Container
createIterator() : Iterator
生成側(コンテナ)と生成される
もの(イテレータ)の間に,パラ
レルなクラス階層が存在する
一般化層
特殊化層
{
具体クラス群
return new ConcreteIterator1( this );
}
ConcreteIterator2
ConcreteIterator1
# currentPosition
# container
: ConcreteContainer2
# currentPosition
# container
: ConcreteContainer1
具体クラス群
ConcreteContainer1
ConcreteContainer2
+ createIterator() : Iterator
+ createIterator() : Iterator
生成
生成
9
Copyright (C) 1999 by Masanori Ohshiro
状態に関するパターン
●Flyweightパターン ●Stateパターン ●Observerパターン ●Mementoパターン
Fig.17[Flyweightパターン]
Flyweightパターン
1
*
《 interface 》
Flyweight
FlyweightFactory
if( キーkeyのflyweightが存在 ) {
return 該当するflyweight;
}
else{
キーkeyのflyweightを生成して
- flyweights
+ getFlyweight( key ) : ConcreteFlyweight {final}
+ getUnsharedFW( ) : UnsharedConcreteFlyweight {final}
operation( extrinsicState )
flyweightsに登録。
return 生成したflyweight;
}
{
一般化層
UnsharedConcreteFlyweight
オブジェクトを生成する
(flyweightsには登録しない)。
return 生成したオブジェクト;
特殊化層
}
具体クラス群
《friend》
利用者
ConcreteFlyweight
User
UnsharedConcreteFlyweight
- intrinsicState
- allState
- ConcreteFlyweight()
+ operation( extrinsicState )
+ UnsharedConcreteFlyweight()
+ operation( extrinsicState )
※ 共有flyweightの具体クラス
※ 共有されないflyweightの
具体クラス
Fig.18[Stateパターン]
Stateパターン
《friend》
1
利用者
User
State
Context
- state : State
+ request() {final}
- changeState( s : State ) {final}
+ Context( initialState : State )
{ abstract }
{
state.handle( this );
}
+ handle( c : Context )
# changeState( c : Context, s : State ) {final}
{
c.changeState(s);
}
{ state = s; }
{ state = initialState; }
一般化層
特殊化層
{
状態A下での操作Handle()
の動作を定義
…
必要が有れば,動作の最後の
ステップに,操作changState()
を呼び出して状態を遷移させる。
}
具体クラス群
10
ConcreteStateA
ConcreteStateB
+ handle( c : Context )
+ handle( c : Context )
状態Aの振る舞いを
記述する具体クラス
状態Bの振る舞いを
記述する具体クラス
Copyright (C) 1999 by Masanori Ohshiro
Fig.19[Observerパターン]
Observerパターン
被観察物
観察者
*
《 interface 》
Observer
Subject
{ abstract }
{
- observers
update( s : Subject )
observersに登録されている
全てのObserverオブジェク
トoに対して,
o.update( this );
を呼び出す
+ attach( o : Observer )
+ detach( o : Observer )
+ notify()
}
一般化層
特殊化層
ConcreteSubjectとConcreteObserver
が1対1対応するときには,パラレルな
クラス階層になる
具体クラス群
User
利用者
具体クラス群
ConcreteSubjectA
ConcreteObserverA
{
- subjectState
operation()
+ getState()
{
return subjectState();
ConcreteSubjectB
- subject : ConcreteSubjectA
- observerState
subjectStateを変化させる操作
…
notify();
}
}
+ update( s : Subject )
if( subject != null ) {
observerState = subject.getState();
}
ConcreteObserverB
Fig.20[Mementoパターン]
Mementoパターン
《friend》
Originator
- state
生成
{
Memento
return new Memento( state );
- state
Mementoオブジェクト生成メソッド
- getState()
- setState()
+ createMemento()
+ setMemento( Memento m )
}
状態復帰が可能なオブジェクト
のクラス
{
if ( m != null ) state = m.getState();
}
Mementoオブジェクトを使った
状態復帰メソッド
Originatorオブジェクト
の内部状態をカプセル化
したオブジェクトのため
のクラス
Caretaker
Mementoオブジェクト
を保存・維持したり,
Originatorオブジェク
トの状態復帰をサポー
トする
※ stateは複数の属性からなるOriginatorオブジェクトの内部状態を表している
※ CaretakerオブジェクトがMementoオブジェクトを逐次,保存・維持するなら,Mementoオブジェクトのstateには,Originator
オブジェクトの状態変化の差分情報を記録するだけでよい
11
Copyright (C) 1999 by Masanori Ohshiro
命令のオブジェクト化
●Commandパターン
Fig.21[Commandパターン]
Commandパターン
命令操作を発行する
オブジェクトのクラス
命令操作の
インタフェイス
Invoker
《 interface 》
Command
- command : Command
{
if( command!= null )
command.execute();
+ invoke()
execute()
}
User
利用者
一般化層
特殊化層
Receiverオブジェクト
の所有者
Client
命令操作メッセージを受信
するオブジェクトのクラス
Receiver
+ action()
実際の
アクション
{
if( receiver != null )
receiver.action();
}
生成
具体クラス群
ConcreteCommand1
ConcreteCommand2
- receiver
- state
- receiver
- state
+ execute()
+ execute()
ここで詳細なアクシ
ョンをしてもよい
12
Copyright (C) 1999 by Masanori Ohshiro
関係を減らすパターン
●Mediatorパターン
※ この他,Adaptorパターンなども
関係を減らすために使用できる
●Facadeパターン
Fig.22[Mediatorパターン]
Mediatorパターン
調停者オブジェクト
のインタフェイス
同僚オブジェクト
の抽象クラス
《 interface 》
Mediator
{ abstract }
Colleague
# mediator
一般化層
特殊化層
ConcreteColleague1
ConcreteMediator
ConcreteColleague2
この部分がひとつの
協調システムをなす
具体クラス群
※ この場合,一般化層はもっぱらColleagueからMediatorへの
抽象的な接続を定義するために用いられる
Fig.23[Facadeパターン]
Facadeパターン
User1
利用者1
Facade
利用者2
User2
サブシステム群
※ 利用者1はFacadeに用意されたシンプルなインタフェイスだけを使用できる
※ 利用者2のように,サブシステム群を直接利用することも可能
13
Copyright (C) 1999 by Masanori Ohshiro
コンテナ要素への操作
●Visitorパターン
●Iteratorパターン
※ Iteratorパターンに関しては,「インタフェイスを
変更する媒介物」の項を参照
Fig.24[Visitorパターン]
Visitorパターン
*
リストや木構造などの
オブジェクト構造体
利用者
ObjectStructure
User
《 interface 》
Element
Elementオブジェクトを処理する
戦略を規定するインタフェイス
《 interface 》
Visitor
visitConcreteElementA( e : ConcreteElementA )
visitConcreteElementB( e : ConcreteElementB )
要素型
accept( v : Visitor )
一般化層
特殊化層
具体クラス群
戦略1
具体クラス群
ConcreteElementA
ConcreteElementB
ConcreteVisitor1
+ accept( v : Visitor )
+ operation( )
+ accept( v : Visitor )
+ operation( )
+ visitConcreteElementA( e : ConcreteElementA )
+ visitConcreteElementB( e : ConcreteElementB )
戦略2
{ v.visitConcreteElementA( this ); }
{ … e.operation( ); … }
ConcreteVisitor2
+ visitConcreteElementA( e : ConcreteElementA )
+ visitConcreteElementB( e : ConcreteElementB )
※ Visitorパターンは,コンテナ要素への機能追加を目的として用いられることが多いが,主たるクラスへ複雑な機能を追加する
ために使用することもできる
14
Copyright (C) 1999 by Masanori Ohshiro