デザインパターンは、ソフトウェアエンジニアが頻繁 それはコードではありません。 それはこれらの問題に取り組み、解決策を設計する方法についての説明のようなものです。

これらのパターンを使用することは、ソリューションの設計が非常に試行され、最終的なコードの可読性が高くなるため、良い習慣と考えられています。, デザインパターンは、JavaのようなOOP言語のために作成され、使用されることが多く、ここからの例のほとんどが書かれています。

デザインパターンの種類

現在発見されている約26のパターンがあります(私はそれらをすべてやるとはほとんど思っていません…)。

これらの26は、3つのタイプに分類することができます:

1。 Creational:これらのパターン設計のためのクラスのインスタンス生成. クラス作成パターンまたはオブジェクト作成パターンのいずれかになります。

2. 構造:これらのパターンは、クラスの構造と構成に関して設計されています。, これらのパターンのほとんどの主な目的は、その構成の多くを変更することなく、関係するクラス(es)の機能を高めることです。

3. 行動:これらのパターン設計によって一つのクラスを伝えます。

この記事では、分類されたタイプごとに一つの基本的なデザインパターンについて説明します。

Type1:Creational-シングルトンデザインパターン

シングルトンデザインパターンは、クラスのインスタンスのみを作成し、そのオブジェクトへのグローバルアクセスポイントのみを提供することを目的としたCreationalパターンです。, Javaでこのようなクラスの一般的に使用される例の一つはCalendarであり、そのクラスのインスタンスを作成できません。 また、独自のgetInstance()メソッドを使用して、使用するオブジェクトを取得します。

シングルトンデザインパターンを使用するクラスには、

シングルトンクラス図
  1. クラスの唯一のインスタンスを保持するプライベート静
  2. プライベートコンストラクタなので、他の場所ではインスタンス化できません。
  3. クラスの単一のインスタンスを返すためのパブリック静的メソッド。,

シングルトンデザインにはさまざまな実装があります。 今日は、;

1の実装について説明します。 イーガーインスタンス化

2. 遅延インスタンス化

3. スレッドセーフなインスタンス化

Eager Beaver

public class EagerSingleton {// create an instance of the class.private static EagerSingleton instance = new EagerSingleton();// private constructor, so it cannot be instantiated outside this class.private EagerSingleton() { }// get the only instance of the object created.public static EagerSingleton getInstance() {return instance;}}

このタイプのインスタンス化は、変数インスタンスのインスタンス化がどのメソッドの外でも起こるため、クラスのロード中に起こります。 このポーズ高額な欠点がこのクラスでは使用されていませんのクライアントアプリケーション. このクラスが使用されていない場合、コンティンジェンシー-プランは遅延インスタンス化です。,

Lazy Days

上記の実装と大きな違いはありません。 主な違いは、静的変数が最初にnullと宣言され、getInstance()メソッド内でのみインスタンス化されることです。

これは一つの問題を修正しますが、別の問題はまだ存在します。 二つの異なるクライアントが同時にシングルトンクラスにアクセスする場合はどうなりますか?, まあ、彼らは同時にインスタンスがnullであるかどうかをチェックし、それがtrueであることを見つけるので、二人のクライアントによる各要求に対して このスレッドに対して安全インスタンス化することが可能になります。

(Thread)Safety is Key

Javaでは、synchronizedキーワードはスレッドセーフティを実装するためにメソッドまたはオブジェクトで使用されるため、一度に一つのスレッドだけが特定のリソースにアクセスするようになります。 クラスのインスタンス生成は以内に同期ブロックの方法のみがアクセス可能である顧客アですることができるものとします。,

同期メソッドのオーバーヘッドが高く、操作全体のパフォーマンスが低下します。

たとえば、インスタンス変数がすでにインスタンス化されている場合、クライアントがgetInstance()メソッドにアクセスするたびにsynchronizedメソッドが実行され、パフォーマンスが低下します。 これは、instance変数の値がnullであるかどうかを確認するために発生します。 そうであることが判明した場合、それはメソッドを離れます。

このオーバーヘッドを減らすために、ダブルロックが使用されます。, チェックはsynchronizedメソッドの前にも使用され、値がnullの場合はsynchronizedメソッドが実行されます。

次の分類に進みます。

Type2:Structural-The Decorator Design Pattern

デコレータパターンを使用する理由と場所について、より良いコンテキストを与えるための小さなシナリオを示します。

あなたはコーヒーショップを所有していると言う、と任意の初心者のように、あなたは普通のコーヒーのちょうど二つのタイプ、ハウスブレンドとダークロースト, 課金システムでは、beverage抽象クラスを継承するさまざまなコーヒーブレンド用のクラスがありました。 人々は実際に来て、あなたの素晴らしいを持って開始します(苦いとはいえ?)コーヒー。 それから、神が禁じる、砂糖や牛乳が欲しいコーヒーニューブがあります。 コーヒーのためのそのような茶番!! ??

今、あなたは両方のメニューに、残念ながら課金システム上で、同様にこれら二つのアドオンを持っている必要があります。 もともと、あなたのIT担当者は、砂糖、他のミルクを含む両方のコーヒーのためのサブクラスを作ります。, その後、顧客は常に正しいので、一つは、これらの恐ろしい言葉を言う:

“私は砂糖で、ミルクコーヒーを得ることができますか?”

???

あなたの課金システムは再びあなたの顔に笑って行きます。 さて、お絵かきボードに戻る….

その後、IT担当者はmilk coffee with sugarを別のサブクラスとして各親coffeeクラスに追加します。 月の残りは順風満帆で、人々はあなたのコーヒーを持っているために並んで、あなたは実際にお金を稼ぐ。 ??

しかし、待って、より多くのがあります!

世界は再びあなたに反対しています。, ライバルは、コーヒーのだけでなく、4種類が、同様に10以上のアドオンで、通りの向こう側に開きます! ?

あなたはより良いコーヒーを自分で販売するために、それらすべてを購入し、より多くの、そしてちょうどあなたがそのdratted課金システムを更新するのを忘 新しいコーヒーブレンドでは、すべてのアドオンの任意およびすべての組み合わせに対して無限の数のサブクラスを作成することはできません。 最終的なシステムのサイズは言うまでもありません。??

実際に適切な課金システムに投資する時間。, あなたは実際に彼らが何をしているかを知っていて、彼らが言う新しいIT担当者を見つけます。

“なぜ、デコレータパターンを使用すると、これははるかに”

それは一体何ですか?

デコレータ設計パターンは、継承、構成、またはその両方によるものであるかどうかにかかわらず、クラスの実際の構造を扱う構造カテゴリに分類さ この設計の目的は、実行時にオブジェクトの機能を変更することです。 これは、他の多くのデザインパターンを利用した抽象クラスおよびインタフェースと組成を獲得するにしていきます。,

数学にチャンスを与えましょう(身震い?)視点にこのすべてをもたらすために、

4コーヒーブレンドと10アドオンを取ります。 私たちは、コーヒーの一つのタイプのすべてのアドオンの各異なる組み合わせのためのサブクラスの生成に固執した場合。 それは;

(10-1)2=92=81サブクラス

あるアドオンを同じタイプの別のアドオンと組み合わせることができないので、1を10から減算します。 そして、それはただ一つのコーヒ その81に4を掛けると、なんと324の異なるサブクラスが得られます!, つるすべての符号化…

ではデコレータのパターンが必要16クラスこのシナリオ。 賭けたいか?

デコレータデザインパターンクラス図
コーヒーショップのシナリオに応じたクラス図

上記のクラス図に従って、4つのコーヒーブレンドに対して4つのクラス、各アドオンに対して10つ、抽象コンポーネントに対して1つ、抽象デコレータに対してさらに1つのクラスを取得します。 ほら! 16!, 今その$100を渡しなさい。?? 上からわかるように、具象coffee blendsがbeverage抽象クラスのサブクラスであるのと同じように、AddOn抽象クラスもそれからそのメソッドを継承します。 そのサブクラスであるアドオンは、必要に応じてベースオブジェクトに機能を追加するための新しいメソッドを継承します。

このパターンが使用されているのを見るために、コーディングに行きましょう。,

最初に抽象beverageクラスを作成し、すべての異なるコーヒーブレンドが継承されます。

次に、両方の具体的なコーヒーブレンドクラスを追加します。

AddOn抽象クラスは、Beverage抽象クラスからも継承します(これについては、以下を参照してください)。

そして今、この抽象クラスの具象実装:

あなたが上で見ることができるように、我々はAddOnの任意のサブクラスにBeverageの任意のサブクラスを渡すことができ、追加されたコストだけでなく、更新された説明を取得することができます。 そして、AddOnクラスは本質的にBeverage型であるため、AddOnを別のAddOnに渡すことができます。, このようにして、特定のコーヒーブレンドに任意の数のアドオンを追加することができます。

これをテストするためのコードを書きます。

最終結果は次のとおりです。

P.S.これはスリランカルピーにあります

それは動作します! すべてのコーヒーブレンドの各アドオンの組み合わせに対して無限のサブクラスを作成する必要なしに、コーヒーブレンドに複数のアドオンを追加し、最終的なコストと説明を正常に更新することができました。

最後に、最後のカテゴリに。,

タイプ3:ビヘイビア-コマンド設計パターン

ビヘイビア設計パターンは、クラスとオブジェクトが相互に通信する方法に焦点を当てています。 コマンドパターンの主な焦点は、関係するパーティー間のより高度な疎結合を教え込むことです(読み:クラス)。

ええと…それは何ですか?

結合は、互いに相互作用する二つの(またはそれ以上の)クラスが相互作用する方法です。 これらのクラスが相互作用するときの理想的なシナリオは、互いに大きく依存しないことです。 それは疎結合です。, したがって、疎結合のより良い定義は、相互に相互接続され、お互いの使用を最小限に抑えるクラスです。

このパターンの必要性は、あなたが何を求めているのか、受信者が誰であるのかを意識的に知らずに要求を送信する必要があるときに生じました。

このパターンでは、呼び出し元のクラスは、実際にアクションを実行するクラスから切り離されます。 呼び出し元クラスには、クライアントが要求したときに必要なコマンドを実行する呼び出し可能なメソッドexecuteのみがあります。

のは、派手なレストランで食事を注文し、基本的な現実世界の例を見てみましょう。, 流れが進むにつれて、あなたはあなたの注文(コマンド)をウェイター(呼び出し元)に与え、それをシェフ(受信機)に渡すので、食べ物を得ることができます。 単純に聞こえるかもしれません…しかし、コードに少しmeh。

アイデアは非常に簡単ですが、コーディングは鼻の周りに行きます。,

コマンドデザインパターンクラス図

技術面での操作の流れは、コマンドインターフェイスを実装する具体的なコマンドを作成し、アクションを完了するように受信機に要求し、呼び出し元にコマンドを送信することです。 呼び出し元は、このコマンドをいつ与えるべきかを知っている人です。 シェフは、特定のコマンド/順序を与えられたときに何をすべきかを知っている唯一の人です。, したがって、呼び出し元のexecuteメソッドが実行されると、コマンドオブジェクトのexecuteメソッドが受信側で実行され、必要なアクションが完了します。,

実装する必要があるのは、

  1. インターフェイスコマンド
  2. コマンドインターフェイスを実装するクラスの順序
  3. クラスWaiter(invoker)
  4. クラスChef(receiver)

だから、コーディングは次のようになります。

Chef、レシーバー

コマンド、インターフェイス

public interface Command {public abstract void execute();}

注文、具体的なコマンド

ウェイター、呼び出し元

public class Waiter {private Order order;public Waiter(Order ord) {this.order = ord;}public void execute() {this.order.execute();}}

あなた、クライアント

上記のように、クライアントは注文を行い、レシーバーをシェフとして設定します。, 注文はウェイターに送信され、注文を実行するタイミング(すなわち、シェフに調理する注文を与えるタイミング)を知ることになります。 呼び出し元が実行されると、Ordersのexecuteメソッドが受信機で実行されます(つまり、シェフにはパスタを調理するコマンドが与えられますか? またはケーキを焼く?).,

最終クライアント出力

クイック要約

この記事では、

  1. デザインパターンとは何か、
  2. デザインパターンの異なるタイプとそれらが異なる理由
  3. 基本的または一般的なデザインパターンとは何ですか
  4. デザインパターンの異なるタイプとそれらが異なる理由
  5. 基本的または一般的なデザインパターンとは何ですか
  6. デザインパターンの種類とそれらが異なる理由
  7. 各タイプのパターン

これが役に立つことを願っています。

投稿のコードリポジトリを見つける、ここに。