Submit Search
Upload
Javaによる理想のデザインパターン
•
Download as PPTX, PDF
•
6 likes
•
3,689 views
T
Tomomi Fujisaki
Follow
JJUG CCC 2016 Fall にて発表したスライド資料です。Java初心者向けのデザインパターン入門講座です。
Read less
Read more
Engineering
Report
Share
Report
Share
1 of 51
Download now
Recommended
JJUG CCC 2015 Spring 「新人エンジニア奮闘記 - Javaって何?からwebサービスを公開するまで -」発表スライド
JJUG CCC 2015 Spring 「新人エンジニア奮闘記 - Javaって何?からwebサービスを公開するまで -」発表スライド
ToshiakiArai
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Chihiro Ito
メンバーのスキルアップ、どうしてる? − Java 100本ノックで新加入メンバーを鍛えてみた −
メンバーのスキルアップ、どうしてる? − Java 100本ノックで新加入メンバーを鍛えてみた −
JustSystems Corporation
ほんとうに便利だった業務で使えるJava SE8新機能(JJUG CCC 2015 Spring)
ほんとうに便利だった業務で使えるJava SE8新機能(JJUG CCC 2015 Spring)
Yuuki Fukuda
インタフェースデザインの心理学 まとめ
インタフェースデザインの心理学 まとめ
akihiro_0228
Hello Java
Hello Java
Chihiro Ito
Scala界隈の近況
Scala界隈の近況
takezoe
とりあえず使えるSBT
とりあえず使えるSBT
Kiyotaka Kunihira
Recommended
JJUG CCC 2015 Spring 「新人エンジニア奮闘記 - Javaって何?からwebサービスを公開するまで -」発表スライド
JJUG CCC 2015 Spring 「新人エンジニア奮闘記 - Javaって何?からwebサービスを公開するまで -」発表スライド
ToshiakiArai
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Chihiro Ito
メンバーのスキルアップ、どうしてる? − Java 100本ノックで新加入メンバーを鍛えてみた −
メンバーのスキルアップ、どうしてる? − Java 100本ノックで新加入メンバーを鍛えてみた −
JustSystems Corporation
ほんとうに便利だった業務で使えるJava SE8新機能(JJUG CCC 2015 Spring)
ほんとうに便利だった業務で使えるJava SE8新機能(JJUG CCC 2015 Spring)
Yuuki Fukuda
インタフェースデザインの心理学 まとめ
インタフェースデザインの心理学 まとめ
akihiro_0228
Hello Java
Hello Java
Chihiro Ito
Scala界隈の近況
Scala界隈の近況
takezoe
とりあえず使えるSBT
とりあえず使えるSBT
Kiyotaka Kunihira
Scalaでのプログラム開発
Scalaでのプログラム開発
Kota Mizushima
Java研修
Java研修
iPride Co., Ltd.
月曜だからデザインパターンでも勉強しよう vol.1 それは何 & Singleton
月曜だからデザインパターンでも勉強しよう vol.1 それは何 & Singleton
Takaaki Hirano
JavaエンタープライズアーキテクチャにおけるHTML5 - Enterprise ☓ HTML5 Web Application Conference ...
JavaエンタープライズアーキテクチャにおけるHTML5 - Enterprise ☓ HTML5 Web Application Conference ...
Yusuke Suzuki
Dark vol4 for_slideshare
Dark vol4 for_slideshare
ara_ta3
デザインパターンの解説とソフトウェア開発における活用のためのプレゼンテーション資料
デザインパターンの解説とソフトウェア開発における活用のためのプレゼンテーション資料
Takumi Yokoyama
Java エンジニアチームが始めやすい Scala コーディングスタイル #ichigayageek
Java エンジニアチームが始めやすい Scala コーディングスタイル #ichigayageek
Kazuhiro Sera
Xtend の紹介
Xtend の紹介
Oda Shinsuke
More Related Content
Similar to Javaによる理想のデザインパターン
Scalaでのプログラム開発
Scalaでのプログラム開発
Kota Mizushima
Java研修
Java研修
iPride Co., Ltd.
月曜だからデザインパターンでも勉強しよう vol.1 それは何 & Singleton
月曜だからデザインパターンでも勉強しよう vol.1 それは何 & Singleton
Takaaki Hirano
JavaエンタープライズアーキテクチャにおけるHTML5 - Enterprise ☓ HTML5 Web Application Conference ...
JavaエンタープライズアーキテクチャにおけるHTML5 - Enterprise ☓ HTML5 Web Application Conference ...
Yusuke Suzuki
Dark vol4 for_slideshare
Dark vol4 for_slideshare
ara_ta3
デザインパターンの解説とソフトウェア開発における活用のためのプレゼンテーション資料
デザインパターンの解説とソフトウェア開発における活用のためのプレゼンテーション資料
Takumi Yokoyama
Java エンジニアチームが始めやすい Scala コーディングスタイル #ichigayageek
Java エンジニアチームが始めやすい Scala コーディングスタイル #ichigayageek
Kazuhiro Sera
Xtend の紹介
Xtend の紹介
Oda Shinsuke
Similar to Javaによる理想のデザインパターン
(8)
Scalaでのプログラム開発
Scalaでのプログラム開発
Java研修
Java研修
月曜だからデザインパターンでも勉強しよう vol.1 それは何 & Singleton
月曜だからデザインパターンでも勉強しよう vol.1 それは何 & Singleton
JavaエンタープライズアーキテクチャにおけるHTML5 - Enterprise ☓ HTML5 Web Application Conference ...
JavaエンタープライズアーキテクチャにおけるHTML5 - Enterprise ☓ HTML5 Web Application Conference ...
Dark vol4 for_slideshare
Dark vol4 for_slideshare
デザインパターンの解説とソフトウェア開発における活用のためのプレゼンテーション資料
デザインパターンの解説とソフトウェア開発における活用のためのプレゼンテーション資料
Java エンジニアチームが始めやすい Scala コーディングスタイル #ichigayageek
Java エンジニアチームが始めやすい Scala コーディングスタイル #ichigayageek
Xtend の紹介
Xtend の紹介
Javaによる理想のデザインパターン
1.
Javaによる理想の デザインパターン 関西Javaグループ らしぇる(藤崎 友美) 1
2.
abstrat • デザインパターンとJava • クラス図の見方 •
様々なパターン 2
3.
デザインパターンとJava デザインパターンとは Javaの修飾子で設計を守る Javaの修飾子 3
4.
デザインパターンとは(1/2) • 過去のソフトウェア設計者が編み出した設計ノウハウを蓄 積し、名前を付け、再利用しやすいように特定の規約に 従ってカタログ化したものである(Wikipedia 再利用性
抽象クラスとインタフェース 継承と委譲 4
5.
デザインパターンとは(1/2) • 過去のソフトウェア設計者が編み出した設計ノウハウを蓄 積し、名前を付け、再利用しやすいように特定の規約に 従ってカタログ化したものである(Wikipedia 再利用性
抽象クラスとインタフェース 継承と委譲 とにかく綺麗な設計のプログラムが 作りたいいいぃぃぃぃ!!!! 5
6.
デザインパターンとは(2/2) 大切なこと • やりたいことを明確にする 目的
現状 手段 結果 • パターンを多く知ること 型にあてはめる知識をつける 6
7.
Javaの修飾子で設計を守る デザインパターンを保ちたい だがしかし コーディング規約だけではプログラムは保守 できない • ルールの必要性が理解されない • ルールが多すぎて覚えきれない •
目視で行うレビューに頼っており負担が大きい 7
8.
Javaの修飾子で設計を守る デザインパターンを保ちたい だがしかし コーディング規約だけではプログラムは保守 できない • ルールの必要性が理解されない • ルールが多すぎて覚えきれない •
目視で行うレビューに頼っており負担が大きい 8 プログラムそのものに制限を設けて デザインパターンを守ろう
9.
Javaの修飾子(1/2) • クラス、インタフェース修飾子 abstract:抽象クラス宣言、継承されることを明示する
final:継承されないことを明示する(インタフェースへの付与は不可) public:すべてのクラスから参照できることを明示する 省略:同一パッケージからのみ参照できることを明示する • メンバ変数修飾子 public:アクセスに制限なし protected:サブクラスからのみ参照可能 private:同一クラス内からのみ参照可能 省略:同一パッケージからのみ参照可能 static:静的宣言、インスタンス化の影響を受けない変数 final:初期値以外変更できない、固定値宣言 tansient:直列化の時に持続的な記憶領域に保存しない volatile:スレッド呼び出し時にマスタから作業用へコピーする 9
10.
Javaの修飾子(2/2) • メソッドの修飾子 public:アクセスに制限なし
protected:サブクラスからのみ参照可能 private:同一クラス内からのみ参照可能 省略:同一パッケージからのみ参照可能 static:静的宣言、インスタンス化の影響を受けない変数 final:初期値以外変更できない、固定値宣言 abstract:抽象メソッド宣言、継承先で実装されることを明示する syncronized:マルチスレッド時に同期を行うメソッド native:C/C++言語などのプラットフォーム依存する箇所への呼び出し • コンストラクタ public:アクセスに制限なし protected:サブクラスからのみ参照可能 private:同一クラス内からのみ参照可能 省略:同一パッケージからのみ参照可能 10
11.
クラス図の見方 クラス 継承 インタフェースの継承 集約 関連依存 11
12.
クラス 12 <<ステレオタイプ>> クラス名 属性(省略可) 操作(省略可) +public -private #protected ~package private
13.
継承 13 ParentClass ChildClass 三角矢印
14.
インタフェースの継承 14 <<interface>> Printable PrintClass 点線の三角矢印
15.
集約 15 Color Fruit - color Basket - fruits 四角のついた矢印
16.
関連依存 16 Uses Creates Notifies 使用する
生成する 通知する
17.
デザインパターン • Iterator • Adapter •
TemplateMethod • FactoryMethod • Singleton • Prototype • Builder • AbstractFactory • Bridge • Strategy • Composite 17 • Decorator • Visitor • Chan of Responsibility • Façade • Mediator • Observer • Memento • State • Flyweight • Proxy • Command • Interpreter
18.
デザインパターン • Iterator • Adapter •
TemplateMethod • FactoryMethod • Singleton • Prototype • Builder • AbstractFactory • Bridge • Strategy • Composite 18 • Decorator • Visitor • Chan of Responsibility • Façade • Mediator • Observer • Memento • State • Flyweight • Proxy • Command • Interpreter
19.
様々なパターン クラス 継承 インタフェースの継承 集約 関連依存 19
20.
Singletonパターン • 1つのインスタンスを使いまわす 20 Singleton -singleton -Singleton() +getInstance() Privateコンストラクタ 自信をインスタンスとして持つ 静的(Static)宣言メソッド 継承不可であるため、final 宣言する
21.
本?匹?個? Iteratorパターン ・繰り返して全ての要素を処理をする 21 <<interface>> Aggregate ConcreteAggregate <<interface>> Iterator ConcreteIterato r Creates +iterator() +iterator() +hasNext() +next() -aggregate +hasNext() +next()
22.
Iteratorサンプルコード Iterator<String> it =
new Iterator<String>(); while(it.hasnext()) { string str = it.next(); System.out.println(str); } 22 そう、 java.util. Listは Iteratorパターンである
23.
Template Methodパターン • 具体的な処理をサブクラスに任せる 23 AbstractClass Class +templateMethod() +method1() +method2() +method3() +method1() +method2() +method3() 抽象(abstract)宣言し、 中身は実装しない 継承先で実装を行う 抽象(abstract)宣言する
24.
Prototypeパターン • 型に依存させずにコピーする 24 Client AbstractPrototype ConcretePrototype Uses +createClone() +createClone() ※Clonable宣言を行った場合ののclone()では コピーするインスタンスにより アドレス参照がコピーされるため、 利用するときは注意が必要。
25.
FactoryMethodパターン • インスタンス化をパターン化する 25 Creator ConcreteCreator Product ConcreteProduct Creates +create() -factoryMethod() -factoryMethod() +method1() +method2() +method3() +method1() +method2() +method3() Creates
26.
Abstract Factoryパターン • 関連する部品をまとめてインスタンス化 26 AbstractProduct1 AbstractFactory AbstractProduct2 Creates +createProduct1() +createProduct2() +createProduct3() +doAlpha() +doBeta() AbstractProduct3 +performOne() +performTwo() +executeA +executeB ConcreteProduct1 ConcreteFactory ConcreteProduct2 +createProduct1() +createProduct2() +createProduct3() +doAlpha() +doBeta() ConcreteProduct3 +performOne() +performTwo() +executeA +executeB Creates Creates Creates Creates Creates
27.
Abstract Factoryパターン • 関連する部品をまとめてインスタンス化 27 AbstractFactory ConcreteFactory AbstractProduct** ConcreteProduct** Creates +createProduct1() +createProduct2() +createProduct3() +createProduct1() +createProduct2() +createProduct3() +executeA() +executeB() +executeA() +executeB() Creates
28.
Bridgeパターン • 機能を「継承関係」と「委譲関係」に分けて拡張性を高める 28 Abstraction RefinedAbstraction <<interface>> Implementor ConcreteImplementor -impl #method1() #method2() #method3() +refinedMethodA() +refinedMethodB() +implMethodX() +implMethodY() +implMethodX() +implMethodY() 継承 委譲
29.
Bridgeパターン • 機能を「継承関係」と「委譲関係」に分けて拡張性を高める 29 Display CountDisplay <<interface>> DisplayImpl StringDisplayImpl -impl #open() #draw() #close() +multiDisplay() +rawOpan() +rawPrint() +rawClose() +rawOpen() +rawPrint() +rawClose() 継承 委譲
30.
Adapterパターン1 • APIが違うクラスの互換性をとる 30 ClientC <<interface>> Target Adapter Adaptee Uses extends
has +targetMethod1() +targetMethod2() -adaptee +targetMethod1() +targetMethod2() +method1() +method2() +method3()
31.
Adapterパターン2 • APIが違うクラスの互換性をとる 31 ClientC <<interface>> Target Adapter Adaptee Uses imprements
extends +targetMethod1() +targetMethod2() +targetMethod1() +targetMethod2() +method1() +method2() +method3()
32.
Builderパターン • 複雑な処理を任せて結果だけ取得する 32 ClientC ConcreteBuilder Director Uses Uses +buildPart1() +buildPart2() +buildPart3() +getResult() -builder +construct() Builder +buildPart1() +buildPart2() +buildPart3()
33.
Strategyパターン • 同じ問題を別の方法で解く 33 Context ConcretStrategy1 <<interface>> Strategy ConcreteStrategy2 -strategy +contextMethod() +strategyMethod() +strategyMethod() +strategyMethod()
34.
Compositeパターン • 容器と中身を同一視して再帰的な構造を作る 34 Client Leaf Component Composite +method1() +method2() +method1() +method2() +add() +remove() +getChild() -children +method1() +method2() +add() +remove() +getChild() Uses
35.
Decoratorパターン • 「飾り付け」を増やす拡張を行う 35 Client ConcreteComponent Component Composite +method1() +method2() +method1() +method2() -component +method1() +method2() Uses ConcreteDecorator +method1() +method2() デコる!
36.
Visitorパターン • 構造を渡り歩いて処理する 36 ConcreteVisitor Visitor Element +visit(ConcreteElement A) +visit(ConcreteElement
B) +visit(ConcreteElement A) +visit(ConcreteElement B) +accept(Visitor) ConcreteElementA +accept(Visitor) ConcreteElementB +accept(Visitor) ObjectStructure Uses Uses 繰り返し処理をパターン化
37.
Chain of Responsibilityパターン •
責任のたらい回し(再帰呼び出し) 37 Client ConcreteHandler1 Handler Concretehandler2 +request() -next +request() Request +request()
38.
Facadeパターン • 一連の処理をまとめて入口を一つにする 38 Client ClassA Facade ClassD ClassB ClassC Uses
39.
Mediatorパターン • 相談役に相談して処理する 39 ConcreteColleague3 +concreteColleague3() ConcreteColleague3 +concreteColleague3() ConcreteColleague3 +concreteColleague3() Colleague -mediator +setMediator() +controlColleague() Mediator +createColleagues() +colleagueChanged() ConcreteMediator -concreteColleague1 -concreteColleague2 -concreteColleague3 +createColleagues() +colleagueChanged()
40.
Observerパターン • 状態の変化を全体に通知する 40 Subject ConcreteSubject Observer ConcreteObserver -observers +addObserver() +deleteObserver() +notifyObservers() +getSubjectStatus() +getSubjectStatus() +update() +update() Notifies
41.
Mementoパターン • 状態を保存する 41 Caretaker Originator +createMemento() +restoreMemento() Memento <<wide
interface>> +getProtectedInfo() <<narrow interface>> +getPublicInfo() Requests Creates
42.
Stateパターン • 状態が変化するタイミングでクラスを切り替える 42 Context ConcretStrate1 State ConcreteStrate2 -strate +requestX() +requestY() +requestZ() +methodA() +methodB() +methodC() +methodA() +methodB() +methodC() +methodA() +methodB() +methodC()
43.
Flyweightパターン • インスタンスをできるだけ共有させて無駄にnewしない 43 +methodA() +methodB() FlyweightFactory - pool +getFlyweight() Client Flyweight Uses Creates Uses
44.
Proxyパターン • 代理人を立てて必要になってから作る 44 Subject +request1() +request2() +request3() Proxy realSubject +request1() +request2() +request3() RealSubject +request1() +request2() +request3() Client Uses Uses
45.
Commandパターン ・命令を表すインスタンスをまとめて管理する 45 Command ConcreteCommand Invoke Receiver Creates +execute() receiver +execute()+action() Client
46.
Interpreterパターン ・文法規則をクラスで表現する 46 Context AbstractExpression NonterminalExpression Client Creates +getInfoToInterpret() +interpret() +interpret() TerminalExpression +interpret() Uses
47.
参考書 47
48.
参考書 48
49.
ご清聴ありがとうございました 49
50.
50
51.
補足:テンプレート宣言 • C++ templete<class T>
class GenericClass{ private T value: public GenericClass(const T& t); } • Java public class GenericClass<T> {} 51
Editor's Notes
Wikipediaより、デザインパターンとは、「過去のソフトウェア設計者が編み出した設計ノウハウを蓄積し、名前を付け、再利用しやすいように特定の規約に従ってカタログ化したものである」と記されています。 C++やJavaなど、オブジェクト指向言語における設計において、保守や拡張性を求めた結果、設計が似通ってきます。 目的に応じてそれら「似通った設計パターン」に当てはめて設計することで、保守にかかるコストを削減しようというのがデザインパターンです。 重要になってくるのが「再利用性」、「抽象クラスとインタフェース」、「継承と委譲」です。 はい、ぱっと言われても意味が分かりませんね。
こういうことです。
まずは、設計上でやりたいことを明確にすること。物事はなんでもこれが当てはまりますが、デザインパターンを使う際は特に気を付けてください。 「結果」を得るための「目的」を明確にし、現時点で上がっている課題など、「現状」を把握して「手段」となるデザインを決定します。 2つめ、デザインパターンは同じような目的のパターンが多数存在します。目的ごとに使い分けなければいけないため、できる限り多くのパターンとその名前を知識として身につけてください。保守する際に「パターン名」が分かっていないと、おかしな設計を行ってしまうこともあります。名前に込められた意味を大事にしてください。
ルールの必要性が理解されない。または、ルール違反に対する正しい対処方法が理解されていない。 ルールが多すぎて覚えきれない。あるいは、ルールが少なくてカバー範囲が不足している ルールの遵守状況を確認するための高精度ツールがなく、確認を技術者が目視で行うレビューに頼っており
ルールの必要性が理解されない。または、ルール違反に対する正しい対処方法が理解されていない。 ルールが多すぎて覚えきれない。あるいは、ルールが少なくてカバー範囲が不足している ルールの遵守状況を確認するための高精度ツールがなく、確認を技術者が目視で行うレビューに頼っており
Javaの修飾子はクラス、インタフェース、メンバ変数、メソッド、コンストラクタで付与できるものが変わってきます。 今回はpublic、private、protected、final、staticくらいしか使いません。 詳しく確認したい方は今後配布する予定の本資料にてご確認ください。
クラス図、いわゆるUML図ですね。
デザインパターンはUMLのクラス図を使い書くパターンが定義されています。まずはクラス図の見方をおさらいします。 クラスは図のように表現されます。上の囲いから、クラス名、属性、操作となります。 クラス名の上に記載されるのはステレオタイプという付加情報です。 属性(クラス内変数)と操作(クラス内メソッド)はそれぞれの名前をリスト化し、記載します。 属性と操作のインデントにはそれぞれpublic、private、protectedを表現する記号を記載します。
クラスの関連性についておさらいします。 継承は子クラス(ChildClass)から親クラスに対し矢印を書き記します。 矢印の先端は白い三角で表現します。
インタフェースの継承は親クラス側にステレオタイプとしてinterfaceと記載し、引く矢印は点線表現します。
集約は属性を保持するクラス側から保持される側に対して矢印を引きます。 始点側に白い四角を描く必要があります。 図ではFruitクラスがColorオブジェクトを持ち、BasketがFruitクラスを複数持っている形となります。 果物はそれぞれ色を持っている、バスケットの中には果物が入っていることをクラス図で表現すると、図のようになります。
関連依存は矢印に付与する文字列により、その意味をなしています。 左から、使用(Uses)、生成(Create)、通知(Notify)を表しています。 なにも付与されていない場合はUsesであると考えてください。 クラス図のおさらいはここまでです。 クラス図の表現は他にも色々と定義がありますが、デザインパターンを学ぶ上でこれだけの情報を知っていれば充分です。
デザインパターンには様々なパターンが定義されています。 全23パターンそんざいします。
といわれていますが、開発環境や現場により、独自に進化したデザインパターンが存在します。
では、Javaの修飾子の重要性について知ることができるSingletonパターンから見ていきましょう Singletonパターンはパターンが一番単純です。 コンストラクタがprivate宣言になっているのがこのパターンの特徴です。 New宣言ができないように縛りがかけてあり、インスタンスを利用する際には関数getInstance()を呼び出して利用するようになっています。 どこで呼び出しが行われても同じインスタンスが利用されるようにするための設計です。 リソースの共有などを行うのに便利なパターンです。
まずはIteratorパターンです。 ループしながらオブジェクトを参照していくときに利用する設計の一つです。 左側が集合(Aggregate)を表すクラスで、左側が反復子(Iterator)クラスです。 Javaのサンプルコードが次のスライドに記載してあります。 IteratorをAggregateで生成し、Iteratorでカウント処理を行っています。 リンゴがバスケットの中に複数入っている状態を想像してください。 反復子で繰り返し処理を行うことはバスケットの中からリンゴを取り出して数を数える(処理という意味合いでは「皮をむく」などする)行為と等価です。 リンゴが1個、2個と数えるのに対し、本であれば1冊、2冊、取りであれば1羽、2羽と、数える対象(ConcreteAggregate)に依存した形で 数え方(ConcreteIterator)を変える必要があることを覚えておいてください。
Iteratorを使用している部分をテンプレートにして書き出したのがこちらのコードです。 JavaではテンプレートライブラリとしてListクラス、Iteratorクラスが定義されているため、ConcreteAggregateやConcreteIteratorはユーザが改めてクラス定義する必要がありません。 このように、デザインパターンもライブラリの一部として採用されているモノが存在しています。 デザインパターンの種類を多く知ることの有用性が分かるよいパターンといえます。
TemplateMethodパターンは単なる継承しているクラス図ですが、抽象クラス(AbstractClass)にのみある関数templateMethod()がポイントです。 templateMethod()内でmethod1()、method2()、method3()を呼び出し、規定の処理をおこないます。 それぞれのメソッドを継承クラス(Class)にオーバーライドさせることで、具体的な処理を継承(サブ)クラスにまかせ、1つの機能を持つ関数に拡張性を持たせています。
PrototypeパターンはClientに型を意識させずにコピーを行うためのパターンです。 Prototypeを継承したクラスはcreateClone()で自身をコピーする機能を実装します。 コンストラクタにて、コピーコンストラクタを用意しても対応しきれない場合に利用します。 実体に依存しない中小多岐な形でコピーをしたい時に使います。 他にも、マウスなどで操作を行う図形や画像エディタなどで図形を表すインスタンスと同じものを作りたい、 しかし、IDは分けて管理したいといった要望があるとき時などに利用します。
FactoryMethodパターンはインスタンス化をパターン化するために使用します。FactoryMethodの抽象クラスを継承することで様々なオブジェクトのインスタンス化をパターン化することができます。利用する側はインスタンスを意識せずに生成を行うことでき、インスタンス側はインタフェースを守ることで様々な形のクラスを定義することができます。このように設計レベルから同じパターンで利用できるものを「再利用性の高い設計」といいます。最初に紹介した「再利用性」という言葉が出てきました。 デザインパターンは「再利用性」を意識された作りになっているため、これまで紹介したパターンはもちろんのこと、これから紹介するパターンも再利用性の高いものとなっています。
さきほどFactoryMethodパターンを説明しました。FactoryMethodは一種類のクラスを生成するのに使用しますが、AbstractFactoyは複数のクラスを要求に応じて作り出すパターンとなっています。 図が大きく見づらくなっているため、少し整理したものを次のページに用意しました。AbstractFactoryが複数のクラスに対するインスタンス用メソッドを提供していることに注目してください。利用する側はConcreteFactoryクラスに対して要求する機能を持ったインスタンスを要求できることで、生成による責任をConcreteFactoryに一任することができるのが特徴です。
一つのクラスに対して拡張を繰り返すと大きくなりすぎることがあります。 この際に利用するのがBridgeパターンです。 1つのクラスを「インタフェースを提供する継承関係」と「機能を実装する委譲関係」に分離することで拡張精度を上げることができます。 継承と委譲の関係の橋渡しをするため、Bridgeパターンと呼びます。 抽象化(Abstraction)クラスをベースに、改善した抽象化(RefinedAbstraction)を用意して各処理のトリガーは下のクラスに一任します。 実際に動作するのは実装者(Implementor)クラスになります。こちらは機能ごとに動作が変わることがるため、インタフェースとなっています。 これだけだとわかりにくいので、クラスに名前を付けて見直してみましょう。
まり地ディスプレイ環境を創造してください。 Bridgeパターンがどういったものか、これで理解しやすくなったかと思います。 StringDisplayImplクラスはほかにっ図形や絵を描くためのクラスがそれぞれ定義されていたりするのだと考えればBridgeの秘める可能性をご理解いただけると思います。
AdapterパターンはAPIが違うクラスを接続するためのデザインです。 フレームワークがバージョンアップした際などによく利用されます。 バージョンアップでインタフェースが変わると、今まで利用していたソースコードが利用できないという問題が発生します。 新しインタフェースをそのまま適用すればよいという話ですが、様々な理由によりそれが可能ではない場合、Adapterを古いインタフェースで呼び出せるよう 用意し、Adapterから新しいインタフェースを呼び出す形にします。 Adapterパターンは2種類あります。 新しいインタフェースのクラスを継承した形で、古いインタフェースをTargetに提供するパターンと 次のスライドに示したTargetを継承したAdapterを使うパターンです。 どちらも目的と得られる結果は同じですので、状況に合わせてパターンを使い分けてください。
様々な機能を持つモジュールに対し、一定の複雑な処理を行わせるときに使用するのがBuilderパターンです。 ClientはConcreteBuilderを生成し、複雑な処理自体はDirectorクラスに委譲して一連の動作を行ってもらいます。 DirectorはBuilderクラスを知っているだけで中身が何か意識することはありませんが、結果としてClientはConcreteBuilderから処理の結果を得られるようになっています。
Strategyパターンは一つの問題に対して幾つもの解答方法をときに利用されます。 Strategy(戦略)という名の通り、方向性の難しい数式や、ユーザーに合わせたAIが必要な場合に有用となります。
Compositはファイルマネージャをベースに考えてもらえるとよいでしょう。 Componentを継承する形でファイル(Leaf)とフォルダ(Composit)があります。 Componentでフォルダに関連する関数が定義されており、中は例外を発行する仕様になっています。 フォルダ(Composite)では関数が全てオーバライドされていますが、ファイル(Leaf)ではadd()やremove()などが必要がないため、 最小限の関数だけがオーバーライドされています。
DecoratorパターンはCompositパターンの拡張パターンです。 Leafを機能拡張するのではなく、Composite側を機能拡張させています。 Leafは単体で元の機能を利用でき、さらに動的に機能を被せて拡張する場合はConcreteDecoratorで利用することができます。
Visitorパターンは繰り返し処理を行うためのパターンです。 Iteratorパターンも繰り返し処理のパターンですが、カウントすることに主眼が置かれています。 繰り返し処理自体を一つの機能として作られているのがVisitorパターンです。 ElementリストをVisitorから一つずつ呼び出して処理を行います。 Elementクラスのaccept()関数の引数としてVisitorがあることに注意してください。 リストに対して行われる繰り返し処理は再帰的に呼び出されることを意味しています。 再帰呼び出しが多いということはメモリの消費量が増えるということです。 Visitorを利用する際にはまずIteratorが利用できないか検討するようにしてください。
Chain of Responsibilityパターンは直訳の通り、責任のたらい回しです。 Handlerを継承したの各ConcreteHandlerクラスは自身で処理できるか否かを判別し、 処理できない場合は保持しているnextインスタンスのrequest()関数を実行します。 Clientは一つのHandlerだけを意識するだけでよいのですが、対象がリストの形をとっているということを把握しておく必要があります。
Façadeパターンは一連の呼び出し処理が複雑になってしまう場合に利用するパターンです。 Façadeクラスが各呼び出しを一手に引き受けるため、インタフェースを単純化することができます。
ConcreteMediatorクラスがConcreteColleagueクラスを保有し、また、Colleagueクラスを保有しているのが特徴のMediatorパターンです。 Mediatorは呼び出された際に適する機能を持つクラスを判別し、実行するConcreteColleagueクラスを決定します。 このMediatorはConcreteColleagueクラス側からも呼び出しが行われる設計になっており、ConcreteColleagueクラスも呼び出し側としてMediatorを利用することができます。
Download now