Join the Stack Overflow Community
Stack Overflow is a community of 6.6 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

Class A has a field factory which produces a product B. factory is injected using dependency injection. Does injecting factory hide the dependency of class A on class Product?

The purpose of asking this question: When coding, I made some code just like the example code and I don't know whether it's good design. I think that hiding dependency may be a bad design.

Example code:

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
    }

}
share|improve this question
1  
A factory is an extra layer of indirection, and it's often unneeded. – Steven Oct 7 '16 at 14:01
    
Please elaborate the purpose of your question. I could answer "yes, it does hide this dependency" but I'm not sure if that helps you. – R2C2 Oct 8 '16 at 16:26

No, getting Product from Factory doesn't hide the dependency. A defines getProduct, which returns Product, so A depends on Product.

Even if you inlined getProduct, A would depend on Factory which in turn depends on Product, which would be just as coupled.

The normal way to decouple A from Product would be to separate the class Product into an interface Product and a class ProductImpl (or whatever), and use either dependency injection or a factory (both at once is usually overkill) to get an instance of Product without knowing the implementation class. Then A would depend only on an interface, which is less coupled than depending on a class.

Side note: B is a confusing variable name, since it looks like a constant or class name. It would be more conventional to use b.

share|improve this answer

Your code only hides a dependency if Product is abstract, and "Product B" is actually an instance of some derivative of that class, like "MobileProduct", if Product is not abstract you only hide the implementation of "Product" and not it's existence.

Or if the factory is the thing that is abstract, then you actually hide the many ways you could produce a Product. For instance if you have a "SqlProductFactory", or "InMemoryProductFactory". Then you hide the dependency on how the products are stored, created, or their origin.

Weather or not factories are good for design or not, highly depends on your problem, and how it is solved. For instance if you are building a big API or library it may make sense to hide some dependencies that the consumer doesn't need to know about. But if you only need to solve "Hello World" or "FizzBuzz" there isn't really need for a class - let alone a factory.

So to answer your questions, does your code hide the dependency? Is it good design? Well in both cases it depends on the problem at hand.

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();
  }
}

Here Game doesn't know anything about HardEnemy or EasyEnemy, it only cares about getting an EnemyBase. It also only knows about the the two public fields, and the speak method that EnemyBase class provides. Which may or may not be a good thing. For instance here it enables us to change the implementations of enemies, without having to change the Game, this let's us focus on developing enemies and test how they affect the game - without having to give any attention to game. So it can be a really good thing, that let's you develop things faster, maybe between teams, or future proof your solution. But it may also be a totally unnecessary layer of complexity -

So to conclude :) It really depends :) (Pun may or may not be intended)

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.