11

私はファクトリパターン(およびストラテジーパターン)と、パターンが持つことができる大きなメリットに慣れてきました。しかし、私は次の状況に苦しんでいます。

以前は、次のようなことをしていました。そこでは、車を作成して保存するマネージャークラスがあります。ここには依存性注入はなく、特に単体テストを試みる場合は実装が不十分です。

public class CarManager
{
    public static Car GetCarFromDatabase(int carId) { return new Car(); }

    public static void SaveCar(Car car) { }
}

Factoriesデータベースからであろうと、どこからであろうと、私のために車を作るためのさまざまな方法がどのようにできるかがわかりました。これは素晴らしい!だから、ここに私の質問があります:

FactoriesQ1:オブジェクトのみをビルドする必要があるというのは私の理解ですが、それは正しいですか?もしそうなら、私の2番目の質問はどうですか?

Q2:オブジェクトをビルドするためにファクトリパターンに従っている場合、オブジェクトを保存するにはどうすればよいですか?これには別のパターンがありますか、それともファクトリパターンを完全に理解していませんか?

4

5 に答える 5

16

Factoryパターンは、オブジェクトの作成に役立つはずです。そのため、「作成」パターンに分類されます。最初の質問に答えるために、オブジェクトを永続化するために使用しないでください。

リポジトリパターンは、オブジェクトを永続メカニズムに保存したり、永続メカニズムからデータを取得したりするために使用する必要がある永続パターンです。Martin Fowlerによると、これは実際には、一般的なデザインパターンとは異なるアプローチが必要なエンタープライズパターンです。

あなたの質問について考えるとき、あなたはSOLIDのS原則を見たいと思います。それは、クラスが単一の責任を持つべきであると述べています。つまり、それは変更する単一の理由を持つべきです。この場合、オブジェクトを作成し、それらを保存(永続化)するオブジェクトについて話すとき、変更する2つの理由があるクラスがあります。リポジトリはオブジェクトを取得してアプリケーションに保存でき、取得はファクトリのように見える(多くの場合、リポジトリ内のファクトリオブジェクトである)ため、単一責任のように見えるかもしれませんが、説明している内容では、オブジェクトには1つの責任が多すぎます。

于 2010-10-27T17:06:20.613 に答える
3

工場はデータを保存してはいけません。データアクセスオブジェクト(DAO)またはテーブルマッパーの方が適しています。

于 2010-10-27T17:05:29.700 に答える
2

すべてはあなたのニーズとあなたが物事をどのようにやりたいかに依存します、パターンは標準ではない慣行です、彼らはコードの再利用を奨励します、パターンは石につかまれません。では、なぜファクトリパターンを使用してオブジェクトを永続化しないのですか?これは、私がこのようなパターンを使用して、さまざまなデータベースとの間でデータを読み書きする問題を解決する方法です。これは、パターンを使用するためのより良い形式ではないかもしれませんが、現在機能しており、拡張可能で、レイヤー間で分散されており、ほとんど誰もがそれを理解することができます:

namespace Domain.App
{
    public class PresentationClass
    {
        private Collection<ISomeOutput> GetData(ISomeInput1 input)
        {   
            ServicesLogicContext logic = new ServicesLogicContext( (MyType) Identifier );
            return logic.GetSomeData(input) as Collection<ISomeOutput>;
        }
        private IMethodResult ExecuteSomeAction(ISomeInput2 input)
        {   
            ServicesLogicContext logic = new ServicesLogicContext( (MyType) Identifier);
            return logic.ExecuteSomeAction(input);
        }
    }
}   

namespace Domain.Logic
{
    public sealed class ServicesLogicContext : ServicesLogicContextBase
    {
        public IList<ISomeOutput> GetSomeData(ISomeInput1 input) 
        {
            DBServices services = DBServicesProvider.CreateServices(SomeIdentifier);
            return DBServicesProvider.GetSomeData(input);
        }
        public IMethodResult ExecuteSomeAction(ISomeInput2 input)
        {
            DBServices services = DBServicesProvider.CreateServices(SomeIdentifier);
            IMethodResult result = services.ExecuteSomeAction(input);
            return result;
        }
    }
}

namespace Domain.Data
{
    public abstract class DBServices : IServices
    {
        public virtual IList<ISomeOutput> GetSomeData(ISomeInput1 input)  {...}
        public virtual IMethodResult ExecuteSomeAction(ISomeInput2 input) {...}
    }

    public class DBServicesSpecific1 : DBServices
    {
        public override IList<ISomeOutput> GetSomeData(ISomeInput1 input)  {...}
        public override IMethodResult ExecuteSomeAction(ISomeInput2 input) {...}
    }

    public class DBServicesSpecific2 : DBServices
    {
        public override IList<ISomeOutput> GetSomeData(ISomeInput1 input)  {...}
        public override IMethodResult ExecuteSomeAction(ISomeInput2 input) {...}
    }

    public sealed class DBServicesProvider
    {
        public static DBServices CreateServices(MyType identifier)
        {
            DBServices result = null;       
            switch(identifier) 
            {
                case MyType.Specific1: result = new DBServicesSpecific1(); break;
                case MyType.Specific2: result = new DBServicesSpecific2(); break;       
            }
            return result;
        }
    }
}
于 2010-10-27T21:06:12.470 に答える
1

一般的に、あなたは間違った角度からこれにアプローチしていると思います。

解決しようとしている問題を特定し、その問題に適合する解決策を探す必要があります。あなたが特定のパターンを発見し、それをあなたが遭遇するすべての問題に適用しようとしているように私には聞こえます。

あなたが投稿したコードであなたが言及する唯一の問題は、ユニットテストが簡単ではないということです。クラスをよりテストしやすくするための1つの解決策は、それらの依存関係を逆にすることです。したがって、このクラスが依存している他のクラスを調べ始め、それらの注入可能な依存関係を作成し始めます。出発点として、依存性逆転/制御の反転について読むことをお勧めします。

于 2010-10-27T17:13:37.650 に答える
1

Q1-はい、オブジェクトの作成にはファクトリパターンを使用するのが理想的です。したがって、ファクトリパターンを使用してCarオブジェクトを作成できます。

Q2-車のオブジェクトを保存するために、ファクトリパターンを使用しないでください。Carオブジェクトの作成を切り離し、Carオブジェクトを保存します。また、要件を正確に理解せずに、車のオブジェクトを保存するためのデザインパターンを提案することは困難です。私の意見では、車のオブジェクトを保存する必要がある場合、おそらく必要なのは、車のマネージャークラスのsaveメソッドだけです。デザインパターンを使いすぎないでください。

于 2010-10-27T17:14:38.653 に答える