0

类别A有一个字段factory其生产的产品B。使用依赖注入来注入factory。是否注入factory隐藏类对类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不隐藏的依赖。 A定义为getProduct,其返回Product,因此A取决于Product

即使您内嵌getProduct,A将取决于Factory,而这又取决于Product,这将会一样。

正常方式解耦AProduct将类Product分离成一个接口Product和类ProductImpl(或其他),并使用任一依赖注入或工厂(无论是在一次通常是矫枉过正),以获得不知道实现类的Product的实例。然后A将只依赖于一个接口,而不是依赖于一个类的耦合。

附注:B是一个令人困惑的变量名称,因为它看起来像一个常量或类名。使用b会更传统。

0

如果Product是抽象的,并且“Product B”实际上是该类的某个派生类的实例,如“MobileProduct”,则 如果Product不是抽象的,则只隐藏“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(); 
    } 
} 

这里游戏对HardEnemy或EasyEnemy一无所知,它只关心获取敌人基地。它也只知道两个公共字段以及EnemyBase类提供的说法。这可能会或可能不会是一件好事。例如,在这里它可以让我们改变敌人的执行方式,而无需改变游戏,这让我们专注于发展敌人并测试它们如何影响游戏 - 而不必关注游戏。所以这可能是一件非常好的事情,让我们更快地开发事情,或者在团队之间进行开发,或者将来可以证明您的解决方案。但是,这也可能是复杂的完全不必要层 -

因此得出结论:)这真的取决于:)(双关语可能会或可能不会被意)