16

全体的なSOLIDプログラミング作業の一環として、ベースフレームワークAPI内にファクトリインターフェイスと抽象ファクトリを作成しました。

人々はすでにファクトリーのCreateメソッドをオーバーロードし始めています。問題は、人々がCreateメソッドにモデルプロパティをオーバーロードしていることです(したがって、ファクトリがそれらを設定することを期待しています)。

私の意見では、プロパティの設定は工場で行うべきではありません。私が間違っている?

public interface IFactory
{
    I Create<C, I>();
    I Create<C, I>(long id); //<--- I feel doing this is incorrect

    IFactoryTransformer Transformer { get; }
    IFactoryDataAccessor DataAccessor { get; }
    IFactoryValidator Validator { get; }
}

更新-SOLIDの原則に慣れていない人のために、以下にいくつかを示します。

単一責任の原則
すべてのオブジェクトが単一の責任を持つべきであり、その責任はクラスによって完全にカプセル化されるべきであると述べています

オープン/クローズ
の原則 この原則の意味は、アプリケーションに追加する必要のある機能のリクエストを取得したときに、サブクラスと新しい実装を追加するだけで、古いクラスを変更せずに処理できるようにする必要があるということです。

依存性逆転の原則
これは、ソフトウェアモジュールを分離する必要があることを示しています。これを実現するには、依存関係を分離する必要があります。

全体的に:
私は答えを知っていると90%確信しています。ただし、すでにSOLIDを使用している方からの良い議論をお願いします。貴重なご意見ありがとうございました。

更新-では、SOLIDファクトリは何をすべきだと思いますか?

IMHO SOLIDファクトリは、適切なオブジェクトインスタンスを提供します...しかし、オブジェクトインスタンス化の複雑さを隠す方法で提供します。たとえば、従業員モデルがある場合は、工場に適切なモデルを入手するように依頼します。DataAccessorFactoryは正しいデータアクセスオブジェクトを提供し、ValidatorFactoryは正しい検証オブジェクトを提供します。

例えば:

var employee = Factory.Create<ExxonMobilEmployee, IEmployee>();
var dataAccessorLdap = Factory.DataAccessor.Create<LDAP, IEmployee>();
var dataAccessorSqlServer = Factory.DataAccessor.Create<SqlServer, IEmployee>();
var validator = Factory.Validator.Create<ExxonMobilEmployee, IEmployee>();

さらに例をとると...

var audit = new Framework.Audit(); // Or have the factory hand it to you
var result = new Framework.Result(); // Or have the factory hand it to you

// Save your AuditInfo
audit.username = 'prisonerzero';

// Get from LDAP (example only)
employee.Id = 10;
result = dataAccessorLdap.Get(employee, audit);
employee = result.Instance; // All operations use the same Result object

// Update model    
employee.FirstName = 'Scooby'
employee.LastName = 'Doo'

// Validate
result = validator.Validate(employee);

// Save to SQL
if(result.HasErrors)
     dataAccessorSqlServer.Add(employee, audit);

更新-では、なぜ私はこの分離に固執するのですか?

責任を分離することで、オブジェクトが小さくなり、単体テストが小さくなり、信頼性とメンテナンスが向上すると思います。より多くのオブジェクトを作成することを犠牲にしてそうすることを認識しています...しかし、それがSOLID Factoryが私を保護するものです...それは、前述のオブジェクトの収集とインスタンス化の複雑さを隠します。

4

3 に答える 3

7

私はそれがDRYの原則に固執していると思います、そしてそれが配線の単純な値である限り、私はそれが問題/違反であるとは思いません。持っている代わりに

var model = this.factory.Create();
model.Id = 10;
model.Name = "X20";

コードベース全体に散らばっているので、ほとんどの場合、1か所に配置することをお勧めします。将来の契約変更、リファクタリング、または新しい要件は、処理がはるかに簡単になります。

このようなオブジェクトの作成とすぐにプロパティの設定が一般的である場合、それはチームが進化したパターンであり、オーバーロードを追加する開発者はこの事実への応答にすぎないことに注意してください(特に良いものです)。このプロセスを簡素化するためのAPIの導入は、実行する必要があることです。

繰り返しになりますが、(あなたの例のように)単純な割り当てに絞り込む場合、特に頻繁に気付くものである場合は、オーバーロードを維持することを躊躇しません。物事がより複雑になると、それは新しいパターンが発見された兆候であり、おそらく他の標準ソリューション(たとえばビルダーパターンなど)に頼る必要があります。

于 2013-01-04T16:08:09.343 に答える
2

ファクトリインターフェイスが(インフラストラクチャのコンポジションルートではなく)アプリケーションコードから使用されていると仮定すると、実際にはサービスロケーターを表します。これは、依存性注入に関するアンチパターンと見なすことができます。Service Locator:役割とメカニズムも参照してください。

次のようなコードに注意してください。

var employee = Factory.Create<ExxonMobilEmployee, IEmployee>();

単なるシンタックスシュガーです。具体的な実装への依存を取り除くことはありませんExxonMobilEmployee

また、弱いタイプのメッセージチャネルと強いタイプのメッセージチャネル、およびサービスロケーションなしのメッセージディスパッチ(これらのインターフェイスがSRPに違反する方法を示しています)およびMarkSeemannによる他の出版物にも興味があるかもしれません。

于 2013-01-04T23:04:38.180 に答える
0

依存性注入の約6か月の経験の後、私は工場がプロパティを設定する必要があるいくつかのケースを発見しただけです。

  1. セッターがとしてマークされていてinternal、プロパティが工場で一度だけ設定されることが期待されている場合。これは通常get、ファクトリを介して実装が作成されることが期待されるterプロパティのみを持つインターフェイスで発生します。

  2. モデルがプロパティインジェクションを使用する場合。プロパティインジェクションを使用するクラスはめったに見られませんが(私もこれらのビルドを避けようとしています)、プロパティインジェクションを見つけ、必要なサービスが他の場所でしか利用できない場合は、選択の余地がありません。

public set結論としては、工場からターを除外します。としてマークされているプロパティのみを設定internalします。クライアントが設定を許可されている場合は、設定する必要のあるプロパティをクライアントに決定させます。これにより、工場で不要な機能を排除できます。

于 2016-03-29T17:48:28.810 に答える