パターンクラス図コレクション 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
© Copyright 2026 Paperzz