How to save an instance of a class outside Factory

I have a factory. I do not want to allow classes created by this factory to be created outside of Factory. If I make them abstract, static, or give them private constructors, they will not be realistic at all! Is this a language restriction or what?

I do not want to allow it

var awcrap = new Extrude2013 (); // BAD !!! awcrap.extrudify (); // I don't want to allow this 

The rest of the code:

 using System; namespace testie { public enum ExtrudeType { Extrude2013, Extrude2014 } public interface IExtrudeStuff { void extrudify(); } public class Extrude2013 : IExtrudeStuff { public void extrudify(){ Console.WriteLine ("extrudify 2013"); } } public class Extrude2014 : IExtrudeStuff { public void extrudify(){ Console.WriteLine ("extrudify 2014"); } } public static class ExtrudeFactory { public static IExtrudeStuff Create(ExtrudeType t) { switch (t) { case ExtrudeType.Extrude2013: return new Extrude2013 (); case ExtrudeType.Extrude2014: return new Extrude2014 (); default: return null; } } } class MainClass { public static void Main (string[] args) { // Now for the pretty API part var o = ExtrudeFactory.Create (ExtrudeType.Extrude2013); o.extrudify (); var p = ExtrudeFactory.Create (ExtrudeType.Extrude2014); p.extrudify (); var awcrap = new Extrude2013 (); // BAD !!! awcrap.extrudify (); // I don't want to allow this } } } 
+6
source share
2 answers

You cannot completely ban it. Regardless of whether this is a β€œlimitation” of language, the subject of opinion, but there are things you might consider:

  • Make the constructor internal . This will allow any type inside the declaring assembly to call the constructor, but nothing outside the assembly. This would mean that any code that you write on this assembly must be responsible for calling the factory, and also means that you cannot declare subtypes of the class in another assembly, since it cannot call the constructor.
  • A similar approach would be to make the class that you represent abstract (or an interface), then declare internal (or even private as a subclass of factory, since it was never referenced outside the factory) that implements the abstract class or interface.
  • Require a token that only the factory constructor in the constructor can provide. This is how the DataTable class works. Although the constructor can still be called, the user would have to go null for the value, and at least it would be obvious that they shouldn't.
+5
source

The whole point of the Factory Pattern is that only Factory knows how to select and create an object, and it provides only object objects, instance objects through an interface, not a specific class. The closure of the private object constructor is due to the fact that Factory itself cannot create it.

Decision:

1- Define an interface class that implements all types of Extrude20XX classes, such as IExtrudeStuff .

2- Wrap Extrude20XX classes inside the Factory class as private nested classes.

3- Implement the IExtrude interface in all ExtrudeXX classes.

4- Write the (static) Create (t) method, for example:

 public static class ExtrudeFactory { public static IExtrudeStuff Create(ExtrudeType t) { { switch (t) { case ExtrudeType.Extrude2013: return new Extrude2013 (); case ExtrudeType.Extrude2014: return new Extrude2014 (); default: return null; } } } 
+2
source

Source: https://habr.com/ru/post/955423/


All Articles