デザインパターン

オブジェクト指向概論
第14講
デザインパターン
立命館大学
情報理工学部
黄 宏軒
1
14.1 デザインパターン
n
デザインパターンとは
q
q
q
設計のパターン.よく出てくるパターンを抽象化して再利用
可能とする.
プログラムそのものの再利用は難しくても,
デザインパターンは再利用しやすい
E. Gamma他3人( GoF: Gang of Fourと呼ばれる)によって
提唱された.
n
n
エリック・ガンマ,ラルフ・ジョンソン,リチャード・ヘルム,
ジョン・ブリシディース著,「オブジェクト指向による
再利用のためのデザインパターン(改訂版)」,
ソフトバンククリエイティブ,1999.
同書では23のデザインパターンを定義している
2
GoFによるデザインパターン
生成に関するパターン
デザインパターン
概 要
AbstractFactory
関連する一連のインスタンスを状況に応じて適切に
生成する方法を提供する
Bulider
複合化されたインスタンスの生成過程を隠蔽する
FactoryMethod
実際に生成されるインスタンスに依存しない、
インスタンスの生成方法を提供する
Prototype
同様のインスタンスを生成するために、
原型のインスタンスを複製する
Singleton
あるクラスについて、インスタンスが単一であること
を保証する
3
GoFによるデザインパターン(続き)
構造に関するパターン
デザインパターン
概 要
Adaptor
元々関連性のない2つのクラスを接続するクラスを作る
Bridge
クラスなどの実装と、呼び出し側の間の橋渡しをする
クラスを用意し、実装を隠蔽する
Composite
再帰的な構造を表現する
Decorator
あるインスタンスに対し、動的に付加機能を追加する.
Filterとも呼ばれる
Facade
複数のサブシステムの窓口となる共通のインターフェー
スを提供する
Flyweight
多数のインスタンスを共有し、インスタンスの構築のた
めの負荷を減らす
Proxy
共通のインターフェースを持つインスタンスを内包し、利
用者からのアクセスを代理する.Wrapperとも呼ばれる
4
GoFによるデザインパターン(続き)
振る舞いに関するパターン
デザインパターン
概 要
Chain of
Responsibility
イベントの送受信を行う複数のオブジェクトを鎖状につ
なぎ、それらの間をイベントが渡されてゆくようにする
Strategy
データ構造に対して適用する一連のアルゴリズムをカ
プセル化し、アルゴリズムの切り替えを容易にする
Template Method
あるアルゴリズムの途中経過で必要な処理を抽象メ
ソッドに委ね、その実装を変えることで処理を変えられ
るようにする
Iterator
複数の要素を内包するオブジェクトの全ての要素に順
にアクセスする方法を提供する。反復子
Mediator
個別のオブジェクトに勝手にアクセスせずに,必ず仲
介者を通してアクセスする
Momento
データ構造に対する一連の操作のそれぞれを記録し
ておき、以前の状態の復帰できるようにする
5
GoFによるデザインパターン(続き)
振る舞いに関するパターン(続き)
デザインパターン
概 要
Observer
インスタンスの変化を他のインスタンスから監視できる
ようにする。Listenerとも呼ばれる
State
オブジェクトの状態を変化させることで、処理内容を変
えられるようにする
Strategy
データ構造に対して適用する一連のアルゴリズムをカ
プセル化し、アルゴリズムの切り替えを容易にする
Template Method
あるアルゴリズムの途中経過で必要な処理を抽象メ
ソッドに委ね、その実装を変えることで処理を変えられ
るようにする
Visitor
データ構造を保持するクラスと、それに対して処理を行
うクラスを分離する
6
Iterator
n
複数の要素が集まっている時,それらに順に
アクセスする
Book
Bookshelf
BookshelfIterator
7
Iteratorのクラス図
<<Interface>>
Aggregate
+iterator ( ) Iterator
Bookshelf
-books
-last
+getBookAt ( )
+iterator ( ) Iterator
Creates ▶
<<Interface>>
Iterator
+hasNext ( ) boolean
+next ( ) Object
BookshelfIterator
-bookshelf
-index
+hasNext ( ) boolean
+next ( ) Object
Book
-name
+getName ( )
8
Iteratorの役割
n
実装とは切り離してアクセスするプログラムを
記述する
Iterator it = bookShelf.iterator();
while (it.hasNext ( ) ) {
Book book = (Book) it.next ( ) ;
System.out.println (book.getName ( ) ) ;
}
hasNext, nextはIteratorのメソッドであり,Bookshelfの実装
に依存しない
9
Adapter
n
n
2つのクラスを接続する.Wrapperと呼ばれることもある
一皮かぶせて再利用する
AC100V
DC12V
電源アダプタ
10
Adapterのクラス図例
n
PrintBannerクラスでは,BannerクラスのshowWithParenと
showWithAsterメソッドを継承して,printWeak,printStrong
メソッドを実装する
=PrintBannerクラスはPrintクラスとBannerクラスをつなぐ
アダプタの役割を果たす
≪interface≫
Print
+printWeak( )
+printStrong ( )
PrintBanner
+printWeak( )
+printStrong ( )
(控え目に)印刷
(強調して)印刷
Banner
+showWithParen( )
+showWithAster ( )
(Hellow)と表示
*Hellow*と表示
Printの機能が追加された
Bannerのラッパー
11
PrintBannerクラスの実装
public class PrintBanner extends Banner implements Print {
public PrintBanner(String string) {
super(string);
}
public void printWeak() {
showWithParen();
}
public void printStrong() {
showWithAster() ;
}
}
12
PrintBannerクラスの使い方
public Class Main {
public static void main (String[] args) {
Print p = new PrintBanner("Hellow");
p.printWeak();
p.printStrong();
}
}
<実行結果>
(Hello)
*Hello*
13
Template Method
n
スーパークラスで処理の大枠(テンプレート)を
定め具体的な内容はサブクラスにまかせる
AbstractDisplay
+open( )
+print ( )
+close()
+display()
CharDisplay
+open( )
+print ( )
+close()
StringDisplay
+open( )
+print ( )
+close()
14
AbstractDisplayクラス
public abstract class AbstractDisplay {
public abstract void open ();
public abstract void print ();
public abstract void close();
public final boid display() {
open();
for (int i = 0; i < 2; i++) {
print();
}
close();
}
}
15
CharDisplayクラス
public class CharDisplay extends AbstractDisplay {
private char ch;
public CharDisplay (char ch) {
this.ch = ch;
}
public void open() {
System.out.print("<<");
}
public void print() {
System.out.print(ch);
}
public void close() {
System.out.print(">>");
}
16
StringDisplayクラス
public class StringDisplay extends AbstractDisplay {
private String string;
public StringDisplay (String string) {
this.string = string;
}
public void open() {
System.out.print("------------");
}
public void print() {
System.out.println(string);
}
public void close() {
System.out.print("-------------");
}
17
AbstractDisplayの使い方
public class Main {
public static void main (String[] args) {
AbstractDisplay d1 = new CharDisplay('H');
AbstractDisplay d2 = new StringDisplay("Hello, world.");
d1.display();
d2.display();
}
}
<実行結果>
<<HH>>
-----------Hello, world.
Hello, world.
-----------18
Factory Method
n
n
インスタンスの生成を別のクラスにまかせる
複数のクラスで,インスタンス生成時に同様の処理を
行いたい場合などに有効
q
例:インスタンス生成時にログ(履歴)をとる
19
Factory Methodのクラス図
n
抽象クラスFactoryを継承してインスタンス作成用のクラスを
生成する.オブジェクトの生成と使用を分離できる.
n
実際にインスタンスを生成する際には,(自分のコンストラク
タを使用せず)インスタンス生成用のクラスに依頼する
Factory
Creates ▶
+create ( owner)
-createProduct
-registerProduct
+use ( )
IDCardFactory
-owners
-createProduct ( )
-registerProduct( )
Product
IDCard
Creates ▶
-owner
+use ( )
20
Factory Methodの実装例
n
n
カードを作ってownerを登録するという手続きだけを定義
カード作成とowner登録の具体的な実装はサブクラスで行う
public abstract class AbstractFactory {
public final Product create(String owner) {
Product p = createProduct(owner);
registerProduct(p);
return p;
}
protected abstract Product createProduct(String owner);
protected abstract void registerProduct(Product product);
}
21
Factory Methodの使い方
public class Main {
public static void main(String[] args) {
Factory factory = new IDCardFactory();
Product card1 = factory.create("服部文夫");
Product card2 = factory.create("田中太郎");
card1.use();
card2.use();
}
}
<実行結果>
服部文夫のカードを作ります.
田中太郎のカードを作ります.
服部文夫のカードを使います.
田中太郎のカードを使います.
22
Singleton
n
インスタンスが1個しか存在しないクラス
n
1つしか存在しないオブジェクト(リソース)について排他制御
を行うために使用する
q
例:共有プリンタの使用
一般の
クラス
シングルトン
クラス
23
Singletonのクラス図
n
n
クラス変数(static)としてsingletonを定義
Singletonクラスのコンストラクタはprivate
⇒勝手にインスタンスを作れない
⇒かわりにインスタンスを取得するメソッドがある
Singleton
-singleton
-Singleton ( )
+getInstance ( )
24
Singletonの使い方
(例)チケットのシリアル番号を生成する
public class TicketMaker {
private int ticket = 1000;
private static TicketMaker singleton = new TicketMaker;
private T icketMaker() {
}
public static T icketMaker getInstance() {
return singleton;
}
public int getNextTicketNumber() {
return ticket++;
}
}
25
Strategy
n
アルゴリズムを切り替える
Context
<<Interface>>
Strategy
-strategy
+contextMethod ( )
+strategyMethod ( )
ConcreteStrategy1
ConcreteStrategy2
+strategyMethod ( )
+strategyMethod ( )
26
Composite
n
n
フォルダーと
ファイルのような
構造
入れ物と中身を同一視する
再帰的な構造を作る
Component
+getName
+add ( )
+remove()
+getChild
Leaf
-name
+getName( )
単独要素
複合要素
Composite
-name
+getName ( )
+add()
+remove()
+getChild
27
Observer
n
n
状態の変化を通知する.
MVCモデルで,モデルが変更された時,様々なビューへ
変更を通知する.
ビュー1
5
8
モデル
ビュー2
28
Observerのクラス図
n
n
n
Observer(観察者)とSubject(観察される対象)の関連を定義
Subjectは自分が変化したらObserverに変化されたことを通知
Observerは,通知を受けたらSubjectに問い合わせて自らの
内容を更新する
AbstractSubject
-Observers
+addObserver (Observer)
+deleteObserver(Observer)
+notifyObservers ( )
1
0..*
Observer集合
≪Interface≫
Observer
-Subject
+update ( )
BarObserver
CircleObserver
Subject
29
AbstractSubjectの実装
import java.util.ArrayList;
import java.util.Iterator;
public abstract class AbstractSubject {
private ArrayList observers = new ArrayList();
public void addObserver(Observer observer) {
observers.add(observer);
}
public void deleteObserver(Observer observer) {
observers.remove(observer);
}
public void notifyObservers() {
Iterator it = ovservers.iterator();
while (it.hasNext()) {
Observer o = (Observer)it.next();
o.update(this);
}
}
}
30
14.2 アナリシスパターン
n
分析レベルのパターン
q
ファウラー(M. Fowler)により提唱されたものが有
名
n
マーティン・ファウラー:「アナリシスパターン―再利用可
能なオブジェクトモデル 」,ピアソンエデュケーション,
2002.
31
パーティ
n
人や組織などに共通する住所録に書くような属性を表現する
クラス
パーティ
名前
住所
電話番号
メールアドレス
人
組織
32
組織
n
会社などの組織階層のモデル
事業本部
子 0..*
組織
事業部
事業本部:組織
親 0,1
事業部1:組織
事業所
事業部2:組織
一般化された
組織階層モデル
事業所11:組織
事業所12:組織
33
組織と責任者
n
組織に対応する責任者のモデル
1
事業本部
1
責任者
1
1
1
責任者
事業部
1
事業所
子 0..*
1 1..*
組織
親 0,1
一般化したモデル
34
14.3 アンチパターン
n
n
失敗したシステム開発に共通するパターン
失敗した原因と対策を考える
q
ウィリアム・J・ブラウン他著:「アンチパターン―
ソフトウェア危篤患者の救出 」,ソフトバンククリエイティブ,
2002.
35
肥満児(The Blob)
n
一つのクラスが処理を独占し,その他のクラスがもっぱら
データのカプセル化を担当する
Item
Library_Main_Control
Person
Name
User_ID
・・・
Current_Catalog
Current_Item
User_ID
Fine_Amount
Add_Item(Item)
Delete_Item(Item)
Edit_Item
Find_Item
Print_Catalog
Sort_Catalog
Search_Catalog
List_Catalog
・・・
Title
ISBN
Author
Qty
・・・
Catalog
Topic
Inventory
・・・
36
Item
Title
ISBN
Author
Qty
・・・
Library_Main_Control
Person
Name
User_ID
・・・
Current_Catalog
Current_Item
User_ID
Fine_Amount
Open_Library
Print
・・・
Add_Item
Delete_Item
Edit_Item
Find_Item
・・・
Catalog
Topic
Inventory
・・・
Print_Catalog
Sort_Catalog
Search_Catalog
List_Catalog
・・・
37
機能的分解(Functional Decomposition)
n
n
別名:オブジェクト無指向アンチパターン
処理のサブルーチンをクラスにする
財務ステータスを変える
顧客を加える
住所を更新する
ローンを計算する
返済スケジュールを
計算する
利息を計算する
返済スケジュールを
変更する
38
ローン
顧客
財務ステータスを変える
顧客を加える
住所を更新する
・・・
顧客の返済
顧客ローン
ローンを計算する
利息を計算する
・・・
返済
ローンの返済
返済スケジュールを計算する
返済スケジュールを変更する
・・・
39