0

クラスAは、製品Bを生成するフィールドfactoryを持っています。 factoryは、依存性注入を使用して注入される。 factoryを注入すると、クラスAの従属性がクラスProductに隠れていますか?工場への注入は依存関係を隠していますか?

この質問をする目的:コーディングするとき、私はコード例のようにコードを作ったが、それが良いデザインかどうかわからない。私は隠れている依存関係が悪いデザインかもしれないと思う。

例コード:

class A 
{ 
    private Factory factory; 

    public A(Factory factory) 
    { 
     this.factory=factory; 
    } 

    public Product getProduct() 
    { 
     return factory.produce(); 
    } 

    public void doSomething() 
    { 
     Product B = getProduct(); 
     // use Product to do something 
    } 

} 
+1

工場は、間接の余分な層であり、それはだ - しかし、また、複雑さの全く不要な層であってもよいですしばしば不要になる](https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=100)。 – Steven

+0

あなたの質問の目的を詳述してください。私は "はい、それはこの依存関係を隠す"と答えることができましたが、それがあなたに役立つかどうかはわかりません。 – R2C2

答えて

0

いいえ、依存関係を隠さないFactoryからProductを取得。 AProductを返すgetProductを定義するので、AProductに依存します。

getProductにインライン化した場合でも、AFactoryに依存します。Productはこれと同様に結合されています。

ProductからAインターフェイスProductとクラスProductImpl(または任意の)にクラスProductを分離し、依存性注入、または工場のいずれかを使用することで分離する通常の方法で取得する(一度に両方は、通常過剰です)実装クラスを知らなくてもProductのインスタンスです。その場合、Aは、クラスに依存するよりも結合度が低いインターフェイスにのみ依存します。

サイドノート:Bは、定数またはクラス名のように見えるため、混乱する変数名です。より一般的なbを使用することになります。

0

あなたのコードは、Productが抽象で、 "Product B"が実際に "MobileProduct"のようなそのクラスの派生物のインスタンスである場合にのみ依存性を隠します。 Productが抽象的でない場合、 "それは存在ではありません。

また、工場が抽象的なものであれば、実際には製品を生産するための多くの方法を隠すことになります。たとえば、 "SqlProductFactory"または "InMemoryProductFactory"がある場合。次に、製品の保存方法、作成方法、またはその起源に依存することを隠します。

天気かどうかは、設計上の問題かどうか、非常にあなたの問題と解決方法によります。たとえば、大きなAPIやライブラリを構築している場合、消費者が知る必要のない依存関係を隠すことは意味があります。しかし、 "Hello World"や "FizzBu​​zz"を解決する必要があるのであれば、クラスは必要ありません。

あなたの質問に答えるには、コードが依存関係を隠していますか?それは良いデザインですか?どちらの場合も、手元の問題に依存します。ここで

EnemyBase { 
int Hitpoints; 
int Damage; 
void Speak(); 
} 

EasyEnemy : EnemyBase { 
    public int Hitpoints = 100; 
    public int Damage = 20; 
    private string Name = "EZGuy"; 
    public void Speak(){ 
     print this.Name + ": I shall destroy you!"; 
    } 
} 

HardEnemy : EnemyBase { 
    public int Hitpoints = 200; 
    public int Damage = 40; 
    private string Name = "Da hard1"; 
    public void Speak(){ 
     print this.Name + ": Your days are numbered!"; 
    }{ 
} 

EnemyFactory { 
    private int EnemiesProduced = 0; 
    public EnemyBase getEnemy(){ 
    if(IsOdd(++this.EnemiesProduced)){ 
     return new EasyEnemy(); 
    } else { 
     return new HardEnemy(); 
    } 
    } 
} 

Game { 
    EnemyFactory enemies; 
    public Game(EnemyFactory factory){ 
    enemies = factory; 
    } 
    public void Start(){ 
    EnemyBase e = factory.getEnemy(); 
    } 
} 

ゲームは、それが唯一のEnemyBaseを得ることについて気に、HardEnemyまたはEasyEnemyについて何も知りません。また、2つのパブリックフィールドと、EnemyBaseクラスが提供するspeakメソッドについても知っています。それは良いことかもしれませんし、良いことではないかもしれません。たとえば、ゲームを変更することなく、敵の実装を変更することができます。これは、ゲームに注意を払うことなく、敵を開発し、ゲームにどのように影響するかをテストしましょう。だから、それは本当に良いことです。それはあなたが物事をより速く、多分チーム間で、あるいは将来的にあなたのソリューションを証明するようにしましょう。 [

だから締結する:)それは実際に依存:)(しゃれがまたは意図してもしなくてもよい)

関連する問題