1

I've been reading everything I can find about Factory/Abstract Factory/Simple Factory/etc. I've been unable to find an answer to this question. I understand the classes the factory creates must implement the same interface, or derive from the same base class. But what happens if the different classes don't end up with the same public interface? I.E. SubClass1 and SubClass2 both derive from BaseClass. Now SubClass1 adds PropertyA, and SubClass2 adds PropertyB. Am I correct in assuming these classes can't be created by a factory, since they don't have the same interface? Or, if they were created as BaseClass, they wouldn't expose their new properties. The same problem exists with a common interface. And if anyone knows an author that addresses this, I'd appreciate a reference.

Thanks so much!

5
  • 2
    They can still have the same interface.If you access them via the interface you cant see the extra properties Commented Mar 31, 2015 at 13:02
  • agree with Ewan. These classes can be created by factory but without casting you cannot use extended properties(methods). You can use casting but for me it looks like bad approach Commented Mar 31, 2015 at 13:19
  • I too agree with Ewan, also Head First Design Patterns is excellent for explaining pattern nuances, including the Factory: amazon.co.uk/Head-First-Design-Patterns-Freeman/dp/0596007124 Commented Mar 31, 2015 at 13:24
  • Yes, they can have the same interface, but my question is what to do when they don't have the same interface. They do implement the same interface, but have public methods that are not contained in that interface, and so those methods can't be seen if created by the factory. Commented Apr 1, 2015 at 9:43
  • I think Disappointed confirmed my suspicion. If I use a factory, I need to explicitly cast the returned object, which sort of negates the value of the factory, besides just being sloppy. I have read "Head First Design Patterns" (an excellent newbie book btw), but again, they use the "best case" scenario. That's great for the kind of book it is (an intro). But I'm always looking for where the holes are, so I don't fall into them. Thanks all! Commented Apr 1, 2015 at 9:51

1 Answer 1

2

I think you have missed the purpose of an interface. If you are using interfaces it may not be best practice to create classes the have public methods which are not part of an interface.

So if your factory produces IAnimal. You should not assume you are getting a Dog class that implements a WagTail method, or a Cat class that LandsOnFeet. You need to define IDog and ICat. (Possibly inheriting from IAnimal).

You then can consider how your factory behaves. You have a couple of options.

A. Generics

You could then create a Generic Factory interface IAnimalFactory which when implemented returns either an IAnimal or the specific type.

public interface IAnimal { int Legs(); } public interface IAnimalFactory<T> where T: IAnimal { IAnimal CreateAnimal(); T CreateSpecificAnimal(); } public interface IDog:IAnimal { void WagTail(); } public interface ICat : IAnimal { void LandOnFeet(); } public class Dog:IDog { //Implementation Excluded } public class Cat : ICat { //Implementation Excluded } public class DogFactory:IAnimalFactory<IDog> { public IAnimal CreateAnimal() { return (IAnimal)CreateSpecificAnimal(); } public IDog CreateSpecificAnimal() { return new Dog(); } } public class CatFactory : IAnimalFactory<ICat> { public IAnimal CreateAnimal() { return (IAnimal)CreateSpecificAnimal(); } public ICat CreateSpecificAnimal() { return new Cat(); } } 

The Generic approach gives you some future proofing if you then decide to implement IDomesticDog or IWildDog, and is my preference, but may be more complex then necessary depending on your needs.

B. Specific Methods per SubClass

You could also create a factory that has functions which create a dog or cat of type IAnimal.

public class AnimalFactory { public IAnimal GetDog() { return (IAnimal) new Dog(); } public IAnimal GetCat() { return (IAnimal) new Cat(); } } 

Now as advised above you can safely cast to IDog or ICat.

I don't think there is one author that will specifically answer your question. However reading about Inversion of Control and Dependency Injection will likely give you the right level of information you need.

Sign up to request clarification or add additional context in comments.

2 Comments

I have to disagree with your statement of "Most every class should implement an interface" Unless the class needs to implement an interface this rule will just lead to lots of useless interfaces.
Fair comment @BradleyUffner I have modified accordingly.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.