デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04designpatterns.pdf ·...

28
Copyright 2009 T. Ogihara Cocoa / Cocoa touchの デザインパターン 2009. 08 荻原剛志

Upload: others

Post on 22-Jul-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

Cocoa / Cocoa touchのデザインパターン

2009. 08 荻原剛志

Page 2: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

デザインパターンとは特にオブジェクト指向における、ソフトウェア部品の組み合わせ方のパターン

過去のソフトウェア設計者が見出し、実践を積んできた設計ノウハウ

これらをまとめ、名前をつけ、再利用しやすいようにカタログ化したもの

Mac OS X / Cocoa touch には、デザインパターンで説明できるAPIの構成がいくつかある

Page 3: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

デザインパターンを学ぶと洗練された設計パターンの典型を知ることができる

個々の設計者の「車輪の再発明」を防ぐ

その手法の利点、欠点が事前に明らか

概念が名付けられており、意志疎通に有用

E. Gamma, R. Helm, R. Johnson, and J. Vlissides, “Design Patterns Elements of Reusable Object-Oriented Software”, 1995(オブジェクト指向における再利用のためのデザインパターン 改訂版, SoftBank Publishing)F. Buschmann, R. Meunier, H. Rohnert, P. Sommerlad, and M. Stal, “Pattern-Oriented Software Architechture: A System of Petterns”, 1996(ソフトウェアアーキテクチャ ソフトウェア開発のためのパターン体系, 近代科学社)

参考図書

[POSA]

[GoF]

Page 4: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

ソフトウェアアーキテクチャソフトウェアは多くの構成要素(コンポーネント)から構成されている。コンポーネントの組み合わせによるソフトウェアの骨組みを表す。✦ 骨組みの一部にデザインパターンが含まれたり、複数のデザインパターンの組み合わせが全体の骨組みを構成することはあり得る。

コンポーネント、コンポーネント相互間と環境との関係、およびその設計と進化を導く原理のうちに具現化された、システムの基本構造である‣ Architecture: the fundamental organization of a system embodied in its

components, their relationships to each other and to the environment and the principles guiding its design and evolution. (IEEE 1472: ANSI/IEEE 1471-2000)

Page 5: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

図式表現(1)

クラス

UMLと順番が逆

インスタンス化

Class Name

操作()操作()データデータ

インスタンス化する側

インスタンス化される側

操作やデータは省略されることがある

疑似コードが添付されることがある

(UMLはこの矢印で「依存」を表現)

実装 擬似コード

Page 6: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

図式表現(2)

継承 スーパークラス

サブクラス

スーパークラス

サブクラス1 サブクラス2

抽象クラス、抽象オペレーションはイタリックで表現

AbstractOperation()Abstract Class

Operation()Concrete Class

Page 7: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

図式表現(3)

オブジェクト間の関係

A B

A B

AはBを「知っている」。AからBの操作を利用できる。

AはBを「一部として保有する」。BはAの構成要素である。AとBのライフタイムは同じ。AからBの操作を利用できる。

B 複数個のBと関係があることを示す。

知り合い(acquaintance)

集約(aggregation)

Page 8: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

Model-View-Controller (1)GUIを持つアプリケーションで、必須と言ってよいデザインパターンModelはシステムの核となるデータと機能を持つ。特定のプラットフォームや入出力から独立している。Viewはユーザに対して情報を提示する。Controllerはイベントを処理し、Viewの表示とModelのデータを書き換える。

controller

model

view

Page 9: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Model-View-Controller (2)

Controller

Observerupdate()

Viewactivate()display()update()

抽象クラス

• ViewとControllerは対で存在• ひとつのModelにViewが複数あってもよい• あるControllerがModelを変更すると、それが他のViewの表示すべてに反映される

Modelattach(observer)detach(observer)notify()getData()service()core datasetOfObservers

handle(event)update()

observers

controllermodel

model

view

[POSA]

Page 10: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

デリゲートあるオブジェクトが、処理できないメッセージを受け取った時に別のオブジェクトに処理を代行してもらう機構。(委譲、デリゲーションとも呼ぶ)

Cocoa環境の場合には、付加的な処理を行ってくれる「増設」オブジェクトといった感じが近い

Page 11: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

デリゲートの例

デリゲート

NSApplication 自作の任意のクラス

デリゲートが指定されており、あらかじめ決められたメソッドが実装されていれば、必要に応じてメッセージが送られる。

・アプリケーションの初期化が終わった → 追加の初期化処理・アプリケーションが隠される → アニメーションなどの停止・アプリケーションが終了する → 終了してもよいか? ...

NSWindow(ウィンドウ)など、デリゲートを用いたプログラミングを前提に設計されているクラスは多い。

(アプリケーション管理)

Page 12: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

デリゲートとサブクラスの違いデリゲートは実行中に動的に変更もできる。複数のオブジェクトに対してひとつのオブジェクトがデリゲートになることもできる。基本的な動作と、追加・拡張する機能を明確に分離してプログラムを作成できる。頻繁に使われる汎用の部品などに有効。デリゲートを持つクラスを簡単に実現するための、言語上の仕組みはない。

- (void)setDelegate:(id)obj;- (id)delegate;

アクセサは以下を使うのが普通

Page 13: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

Template Method パターン

アルゴリズムの記述において、サブクラスで決定すべき処理は抽象メソッドとしておき、実装の変更を容易にする。

ApplicationAddDocument()OpenDocument()DoCreateDocument()CanOpenDocument()AboutToOpenDocument()

DocumentSave()Open()Close()DoRead()

MyDocument MyApplication

docsif ( ! CanOpenDocument(name)) { // cannot handle this document return;}

Document* doc = DoCreateDocument();

if (doc) { _docs->AddDocument(doc); AboutToOpenDocument(doc); doc->Open(); doc->DoRead();}

DoRead() DoCreateDocument()CanOpenDocument()AboutToOpenDocument()

(GoF: 振る舞いに関するパターン)

Page 14: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

Template Method パターン

✦ アルゴリズムの不変な部分をまず実装し、振る舞いが変わり得る部分の実装はサブクラスに残しておく場合。

✦ サブクラス間で共通の振る舞いをする部分は抜き出して、これを共通のクラスに局所化する場合。•同じコードがあちこちに現れることがないようにする

✦ サブクラスの拡張を制御する場合。•特定の時点で “hook” operation を呼び出すテンプレートメソッドを定義することができる。

オブジェクト指向プログラミングで一般的に使われる手法である。Cocoa / Cocoa touch でも、サブクラス化を前提とした多くのクラスで使われている。

Page 15: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

Observer パターンオブジェクトの状態変化を他のオブジェクトに自動的に知らせる。

a b cx 60 30 10y 50 30 20z 80 10 10

01020304050

a b c

20%

30%50%

a = 50b = 30c = 20subject

変更の通知変更の通知変更の

通知

値の取得、変更

値の取得、変更

値の取得、変更 各オブジェクトが

互いの実装を知る必要はない。

(GoF: 振る舞いに関するパターン)

Page 16: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

Observer パターン

構造

Update()Observer

Attach(Observer)Detach(Observer)Notify()

Subject

return subjectState;

for all o in observers { o->Update();}

Update()ConcreteObserver

observerState

observers

GetState()SetState()

ConcreteSubject

subjectState

subject

observerState = subject->GetState();

変化があったら observerに知らせる

通知があったら subjectの状態を調べる

Page 17: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

Observer パターン抽象化により、2つの面が、一方が他方に依存しているという形で現れる場合。これらの面をそれぞれ別々のオブジェクトにカプセル化することにより、それらを独立に変更したり、再利用することが可能になる。あるオブジェクトを変化させるとき、それに伴い他のオブジェクトも変化させる必要があり、しかも変化の必要があるオブジェクトを動的に決定したい場合。オブジェクトが、他のオブジェクトに対して、そのオブジェクトが何かを仮定せずに通知できるようにする場合。Foundation では NSNotificationCenterクラスを用いて実現する(通知)。AppKit で Cocoaバインディングを使っても実現できる。

Page 18: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

Singleton パターンあるクラスのインスタンスがただひとつであることを保証する。

インスタンスインスタンス化の操作を用意し、常に同じインスタンスを値として返す。

SingletonClassstatic Instance()

static uniqueInstance

return uniqueInstance;

(GoF: 生成に関するパターン)

構造 クライアントは、唯一のインスタンスに対し、必ずクラスオペレーション Instance を通してアクセスする。

Page 19: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

Singleton パターン適用可能性:クラスに対してインスタンスが1つしか存在してはならず、また、公開されたアクセスポイントを通してそのインスタンスにアクセスできなければならない場合。

Cocoa / Cocoa touch では多くのクラスに「常にデフォルトのインスタンスを返す」クラスメソッドが用意されている。

[UIApplication sharedApplication]

[UIPasteboard generalPasteboard]

[UIAccelerometer sharedAccelerometer]

Page 20: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

Chain of Responsibility パターン

鎖状につながれた複数のオブジェクトにイベントを渡し、いずれかのオブジェクトにそれを処理する機会を与える。

アプリケーション

セーブパネル プリントパネル

印刷ボタンキャンセルボタン

イベントが渡される向き

ボタンが処理するイベントならボタンのオブジェクトが処理。そうでなければパネルが処理。パネルも処理できなければアプリケーションが処理する。

(GoF: 振る舞いに関するパターン)

テキスト

Page 21: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

Chain of Responsibility パターン

HandleRequest()Handler

構造Client

successor

クライアントが要求を出すと、ある ConcreteHandler オブジェクトがそれに対する処理を引き受けるまでは、その要求はチェーンに沿って転送されていく。

HandleRequest()ConcreteHandler2

HandleRequest()ConcreteHandler1

AppKit / UIKit で Viewの階層構造に対するイベント処理に用いられ、レスポンダ・チェーンと呼ばれる。エラーをメソッドの呼び出し側に返す際にも使われ、エラー・レスポンダ・チェーンと呼ばれる。

Page 22: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

Factory Method パターン

インスタンス生成のインタフェースだけを提供し、実際のインスタンスの生成方法はサブクラスが定義する。

ファイル新規...ファイルを開く...保存別名で保存...

CreateDocument()OpenDocument()SaveDocument()

ApplicationCreate()Open()Save()

Documentdocs

具体的なアプリケーション 具体的な

文書メッセージ送信

(GoF: 生成に関するパターン)

Page 23: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

Factory Method パターン

MyApplicationCreateDocument()

構造

MyDocument

Document *doc;doc = CreateDocument();docs.Add(doc);doc->Open();

CreateDocument()NewDocument() OpenDocument()

ApplicationCreate()Open()Close()Save()

Documentdocs

return new MyDocument;

AppKitには NSDocument、 NSDocumentController、および NSWindowController クラスが用意されている。操作対象のファイルに応じ、それぞれのサブクラスを定義する。

Page 24: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

Bridge パターン

抽出されたクラスとその実装を、橋渡しをする構造で分離し、実装を隠蔽する。

Bridge

DrawText()DrawRect()

Windowimp DevDrawText()

DevDrawRect()

WindowImp

TransientWindowIconWindowDevDrawText()DevDrawRect()

DevDrawText()DevDrawRect()

XWindowImp PMWindowImp

XDrawLine();

実装する環境に応じて、 Windowクラスの imp を切り替えればよい。

XDrawString();

(GoF: 構造に関するパターン)

Page 25: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

Bridge パターン 構造

Operation()Abstraction

imp

OperationImp()Implementor

RefinedAbstraction

imp->OperationImp();

OperationImp()ConcreteImplementorA ConcreteImplementorB

OperationImp()

Abstraction クラスは、クライアントからの要求を Implementor のオブジェクトへ転送する。

Client

Page 26: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

Bridge パターン抽出されたクラスとその実装の永続的な結合を避けたい場合。抽出されたクラスとその実装の両方を、サブクラスの追加により拡張可能にすべき場合。

AppKitで画像を扱う NSImage は、イメージの実体の表現を NSImageRep クラスに任せている。 NSImageRepは具体的なデータ形式に対応して NSBitmapImageRep、 NSPDFImageRep などのサブクラスを持つ。 NSImageRepのサブクラスは追加することもできる。

Page 27: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

Proxy パターンあるオブジェクトへのアクセスを制御するために、代理となるオブジェクトを提供する。(別名 Surrogate、Wrapper)

2007年6月に米国、欧州で発売され、ブームを巻き起こしたアッパレ社製の携帯端末「iPbone」が7月11日に国内販売を開始の予定。大手メディア各社の事前アンケートでは、半数近くが「興味がある」、「検討する」と回答。音楽や映像を楽しめる点が魅力に挙げられていますが、おサイフ携帯機能やワンセグが使えないことに不満もあるようです。

2007年1月に全世界で発売され、ブーイングを巻き起こしたマグロソフト社のパソコン用基本ソフト「Windowz Bista」。ニュース各社が行ったアンケート調査では、半数以上が「購入予定がない」、「XPを使う」、「様子を見る」と回答。何が新しいのか利用者に分かりにくい上に、処理能力の高い新型マシンに買い替えなければ快適に動作しない点も不満を増大させている点とか。

ITトレンドニュース

?

Draw()Load()

Graphic

Draw()Load()

ImageProxyDraw()Load()

Imageimage

ImageProxy

文字などと同様なグラフィック要素として扱うと同時に、画像がロードできるまでは代わりに枠を表示しておく。

(GoF: 構造に関するパターン)

Page 28: デザインパターン - ylb.jpylb.jp/iphonekyotod/pdf/04DesignPatterns.pdf · Model-View-Controller (2) Controller Observer update() View activate() display() update() 抽象クラス

Copyright 2009 T. Ogihara

Proxy パターン適用可能性:以下の4つの類型に分類できる✦ remote proxy は、別のアドレス空間にあるオブジェクトのローカルな代理を提供する。

✦ virtual proxy は、コストの高いオブジェクトを要求があり次第生成する。

✦ protection proxy は、実オブジェクトへのアクセスを制御する。オブジェクトごとに異なるアクセス権が必要なときには、この protection proxy は有用である。

✦ smart reference は、通常のポインタに代わるものである。オブジェクトがアクセスされるときに、その smart reference はさらにアクションを実行する。

Foundation には NSProxy があり、分散オブジェクトへのメッセージの転送に使われている。