抽象工場、工場法、ビルダー
質問
これは質問であるかのように見えるかもしれませんが、私に耐えてください - 私は関連する投稿を読んだことを約束します(そして Gof Book).
私が読んだことを何よりも後に、抽象的な工場、工場の方法、またはビルダーをいつ使用するかはまだ明確ではありません。たとえば、問題の簡単な例を見た後、最終的に沈むと思います。 ビルダー そして、たとえば、それを使うのは明らかにばかげているでしょう 抽象的な工場.
他のパターンではなく、1つのパターンをはっきりと使用する簡単な例を提供できますか?
例があまりにも単純すぎる場合、それは意見の問題に要約されるかもしれませんが、誰かができればその人がそうしていることを期待しています。
ありがとう。
解決
ビルダーは、複雑なオブジェクトを構築するのに役立ちます。例は次のとおりです StringBuilder
クラス (ジャワ, C#)、最終的な文字列のピースを少しずつ構築します。より良い例は次のとおりです uricomponentsbuilder 春には、URIの構築に役立ちます。
工場の方法では、1発の完全なオブジェクトを提供します(ビルダーとは対照的に)。ベースクラスは、インターフェイス(またはスーパークラス)参照を返す単一の抽象メソッドを定義し、オブジェクトのコンクリート作成をサブクラスに定ルします。
抽象的な工場は、さまざまな関連するオブジェクトを作成するためのインターフェイス(または抽象クラス)です。良い例(.net)はです DbProviderFactory
具体的な実装に応じて、特定のデータベースプロバイダー(Oracle、SQL Serverなど)に関連するオブジェクト(接続、コマンドなど)を作成するのに役立ちます。
他のヒント
ビルダー
// Builder encapsulates construction of other object. Building of the object can be done in multiple steps (methods)
public class ConfigurationBuilder
{
// Each method adds some configuration part to internally created Configuration object
void AddDbConfiguration(...);
void AddSmtpConfiguration(...);
void AddWebServicesConfiguration(...);
void AddWebServerConfiguration(...);
// Returns built configuration
Configuration GetConfiguration();
}
工場法
// Factory method is declared in base class or interface. Subclass defines what type is created by factory method.
public interface ICacheProvider
{
ISession CreateCache(); // Don't have to return new instance each time - such decission is part of implementation in derived class.
}
public class InMemoryCacheProvider : ICacheProvider
{ ... }
public class DbStoredCacheProvider : ICacheProvider
{ ... }
// Client code
ICacheProvider provider = new InMemoryCacheProvider
ICache cache = provider.CreateCache();
抽象的な工場
// Abstract factory defines families of platform classes - you don't need to specify each platform class on the client.
public interface IDbPlatform
{
// It basically defines many factory methods for related classes
IDbConnection CreateConnection();
IDbCommand CreateCommand();
...
}
// Abstract factory implementation - single class defines whole platform
public class OraclePlatfrom : IDbPlatform
{ ... }
public class MySqlPlatform : IDbPlatform
{ ... }
// Client code:
IDbPlatform platform = new OraclePlatform();
IConnection connection = platform.CreateConnection(); // Automatically Oracle related
...
抽象工場、工場法、ビルダー :これらのパターンはすべて、創造的なパターンであり、 オブジェクトの作成メカニズムを扱う設計パターン, 、状況に適した方法でオブジェクトを作成しようとしています。
工場の方法:
- オブジェクトを作成するためのインターフェイスを定義します, 、しかし、サブクラスにインスタンス化するクラスを決定させます
- 作成ロジックをクライアントに公開せずにオブジェクトを作成します 共通のインターフェイス(または抽象クラス)を使用して、新しく作成されたオブジェクトを参照してください
- アプリケーション固有のクラスをコードにバインドする必要性を排除することにより、ゆるいカップリングを提供します. 。コードは、インターフェイスまたは抽象クラスとのみ相互作用します
使用する場合があります 継承またはサブクラス 目的を達成するため
キーノート:これらのインターフェイスのインターフェイスと特定の実装を作成します。工場法では、条件に応じて、共通インターフェイスの具体的な実装が得られます。
抽象工場:
- 関連するオブジェクトまたは依存オブジェクトのファミリを作成するためのインターフェイスを提供する 具体的なクラスを指定せずに
- カプセル化する階層:可能性が多くあります 「プラットフォーム」 `、および一連の「製品」の建設
- 抽象的な工場のクラスは、多くの場合、工場の方法で実装されます, 、しかし、それらはプロトタイプを使用して実装することもできます
ビルダー:
- ビルダーパターンは、単純なオブジェクトを使用してステップバイステップアプローチを使用して複雑なオブジェクトを構築します
- このシナリオにおける工場の方法/抽象工場への交換 :クライアントプログラムから工場クラスに渡すには、エラーが発生しやすい可能性があるという議論が多すぎる
- 一部のパラメーターは、すべてのパラメーターを送信することを強制する工場とは異なり、オプションである場合があります
Javaのビルダーデザインパターンのガイドライン
- クラス内でビルダーと呼ばれる静的ネストクラスを作成します。
- ビルダークラスには、まったく同じフィールドのセットがあります 元のクラスとして
- ビルダークラスは、成分を追加する方法を公開します. 。各メソッドは同じビルダーオブジェクトを返します。ビルダーは、各メソッド呼び出しで濃縮されます。
- builder.build()メソッドは、すべてのビルダーフィールド値を実際のクラスにコピーし、アイテムクラスのオブジェクトを返します
- アイテムクラス(ビルダーを作成しているクラス) build()メソッドからオブジェクトを作成し、部外者がコンストラクターにアクセスするのを防ぐためのプライベートコンストラクターが必要です。
関連記事:
ビルダーを別々のクラスに保つ(流fluentインターフェイス)
有用なリンク:
ソースメイキング デザインパターン
抽象的な工場パターンは、(工場の)サブクラス化を使用して生産します 他のオブジェクト (非ファクトリ)。抽象工場は、生成されたオブジェクトが並列階層に属していることも想定しています(たとえば、プラットフォームの独立性、各プラットフォームの1つの階層を処理するため)。
ビルダーパターンはサブクラスを使用して「出力」を生成します。 必ずしもオブジェクトではありません. 。 GOFの例には、テキスト出力(マークアップまたはその他)を生成するビルダーがあります。
他の2つとは異なり、ファクトリーメソッドパターン、 「作成者」を抽象的で具体的な実装に分割します (したがって、フレームワークの実装に属することに重点を置いています)。抽象工場のように、実際のオブジェクトの作成を扱っています。
3つすべてが非常に似ています。これは、すべてサブクラス化を使用しているためです。それはそれらすべての優れた品質であるサブクラス化であり、微妙な違いを隠している(上記の概要)。したがって、多くの人が違いを見るのが困難です。
抽象工場は、テスト駆動型の開発と結合の削減に特に役立ちます。
たとえば、C#:
public class Worker
{
public IConsumerFactory Factory { get; set; }
private IResource resource;
public DoWork()
{
IConsumer consumer = Factory.CreateConsumer();
consumer.Consume(resource);
}
}
public interface IConsumerFactory
{
IConsumer CreateConsumer();
}
public interface IConsumer
{
void Consume(IResource resource);
}
public class DefaultConsumerFactory : IConsumerFactory
{
public IConsumer CreateConsumer()
{
return new DefaultConsumer();
}
}
public class DefaultConsumer : IConsumer
{
public void Consume(IResource resource)
{
... Do Work ...
}
}
このようにして、依存関係インジェクションを使用して、生産コードのデフォルトの実装を注入することができます。その後、ファクトリーと作成するオブジェクトを簡単にモックできます。
- ファクトリーメソッドパターン - 複雑なオブジェクトのファミリを構築する場合。
- オブジェクトビルダーパターン - ユーザーがカスタム実装をフレームワークにプラグインすることを許可する場合
詳細については、次のURLをご覧ください。