私はデザインパターンの基本を読んでいて、構造パターンと行動パターンの2つの基本的な定義に出くわしました。
構造設計パターン: 通常、エンティティ間の関係を処理して、これらのエンティティが連携しやすくします。
行動設計パターン: エンティティ間の通信で使用され、これらのエンティティの通信をより簡単かつ柔軟にします。
それを読んで、私はそれらを区別することはできません。
私はデザインパターンの基本を読んでいて、構造パターンと行動パターンの2つの基本的な定義に出くわしました。
構造設計パターン: 通常、エンティティ間の関係を処理して、これらのエンティティが連携しやすくします。
行動設計パターン: エンティティ間の通信で使用され、これらのエンティティの通信をより簡単かつ柔軟にします。
それを読んで、私はそれらを区別することはできません。
説明する最善の方法は、2 つのカテゴリから 2 つの例を取り上げることです。
構造パターンからの複合は、ツリーのような構造を定義するため、関係に焦点を当てます。1 対多で、全体と一部を同じように扱うことができるような関係があります。
一方、行動設計パターンからの観察者パターンは、コミュニケーションに焦点を当てています。オブジェクトへの変更を関係者にどのように知らせるか。パブリッシャーからサブスクライバーへの並べ替え。厳密な構造を定義しませんが、実装方法、つまり通信チャネルを強制します。
それが役に立つことを願っています。
行動を構造の外部のシナリオと考えてください。特定のデータ構造は、複数の動作/シナリオで「使用」できます。
一方、構造関連のロジックは、構造の内部にあると考えてください。構造はさまざまな変更の影響を受け、結果としていくつかのアクションを実行します。
そうは言っても、次の例で例証できます。
構造設計パターンは、その構成要素を記事/画像/コメントなどのより高いレベルのビジネス オブジェクトとして定義することにより、ウェブログを定義します。構成員はお互いを認識しており、相互に接続する方法を知っています。
$image = new Image;
$image->title = 'Image title';
$image->url = 'http://example.com/file.ext';
$image->save(); // will save the image to a DB
$article->title = 'The title i have set';
/* $article->url_key = 'the_title_i_have_set'; */
// this ^^ element of logic will be done automatically by the article
$article->addImage($image); // will save the connection between the
// article and the image to DB
動作設計パターンは、Article/ArticleToImage/Image/ArticleToComment などの下位レベルのビジネス オブジェクトを使用して、ユース ケース (シナリオ) によって Weblog を定義します。ビジネス オブジェクトは相互に認識されず、シナリオ ロジックによって所定の位置に「操作」されます。
$image = new Image;
$image->title = 'Image title';
$image->url = 'http://example.com/file.ext';
$image->save(); // will save the image to a DB
$article->title = 'The title i have set';
$article->url_key = $controller->getURlKey($article->title);
$article->save(); // saves article to DB
$article_to_image = new ArticleToImage;
$article_to_image->article = $article;
$article_to_image->image = $image;
$article_to_image->save();
ストレージ オブジェクトがスマート (ロジックを含む) である場合、それは構造設計です。ストレージ オブジェクトがダム (データを保存して DB に転送することしかできない) の場合は、それらを管理するための動作設計が必要です。
申し訳ありませんが、私の説明は C# になります。
オブザーバーは行動パターンです: インターフェースを提示し、オブジェクトが相互に具体的な知識がなくても通信できるようにします。Publish-Subscribe パターンとも呼ばれます。これらのオブジェクトが何であるかを知らずに、その状態について他のオブジェクトに通知するオブジェクト。
アダプターは構造パターンです。アダプターは、指定されたクラスのインターフェイスをクライアントから要求された別のクラスに変換します。既存のクラスを新しいインターフェイスでラップします。古いコンポーネントと新しいシステムのインピーダンスを一致させます。互換性のないインターフェースのためにこれが不可能な場合に、クラスが連携できるようにします。
アダプターの例:
interface ITarget
{
List<string> GetProducts();
}
public class VendorAdaptee
{
public List<string> GetListOfProducts()
{
List<string> products = new List<string>();
products.Add("Gaming Consoles");
products.Add("Television");
products.Add("Books");
products.Add("Musical Instruments");
return products;
}
}
class VendorAdapter:ITarget
{
public List<string> GetProducts()
{
VendorAdaptee adaptee = new VendorAdaptee();
return adaptee.GetListOfProducts();
}
}
class ShoppingPortalClient
{
static void Main(string[] args)
{
ITarget adapter = new VendorAdapter();
foreach (string product in adapter.GetProducts())
{
Console.WriteLine(product);
}
Console.ReadLine();
}
}
オブザーバーの例: イベント ハンドラーとイベントのみ
using System;
namespace wildert
{
public class Metronome
{
public event TickHandler Tick;
public EventArgs e = null;
public delegate void TickHandler(Metronome m, EventArgs e);
public void Start()
{
while (true)
{
System.Threading.Thread.Sleep(3000);
if (Tick != null)
{
Tick(this, e);
}
}
}
}
public class Listener
{
public void Subscribe(Metronome m)
{
m.Tick += new Metronome.TickHandler(HeardIt);
}
private void HeardIt(Metronome m, EventArgs e)
{
System.Console.WriteLine("HEARD IT");
}
}
class Test
{
static void Main()
{
Metronome m = new Metronome();
Listener l = new Listener();
l.Subscribe(m);
m.Start();
}
}
}
構造パターンは、システムの静的プロパティを定義するために使用されます (クラス図を参照)。
例: Factory パターンを使用して、システムを構成するエンティティを作成できます。Windows と OS X で異なるグラフィカル プロパティを持つオブジェクトButton
を作成できます。Factory パターンはButton
OS に関係なく を作成し、作成されたオブジェクトは両方の OS で同じインターフェイスを持ち、内部が異なっていても同じ動作を公開します。
動作パターンは、システムの動的な動作を定義するために使用されます (アクティビティ、シーケンスなどの図を参照)。
例: アダプター パターンを実行時に使用して、それらの間でインターフェイスを共有しない 2 つのエンティティのインターフェイスを透過的に許可できます。実行時のオブジェクトの動作を効果的に変更します。