I have a class T and a factory TFactory that creates objects of type T.
I want to make sure that only the factory is allowed to create new T objects.
A halfhearted solution would be to require the factory as a parameter in T's constructor, for the only purpose that only somebody who at least brings a factory object can create T's:
class T
{
public T(TFactory Tf)
{
if (!(Tf is TFactory))
throw new InvalidOperationException("No factory provided");
}
}
But wherever a TFactory is at hand, one could construct T's.
Another approach would be to check via stack tracing, if the constructor call really came from within a TFactory, but this seems overkill to me.
A third apporach would be to put both T and TFactory in an assembly of their own, ad make T's constructor internal. But a new project and assembly just for this purpose?
Any better idea anybody?
(Although my code is C#, this is probably a more general question)
Here's something very similar to your third approach: declare the factory as a inner class of T, and make T's constructor private:
public class T {
public class Factory {
public T GetT() {
return new T(); // simple implementation just for an example here
}
}
private T() {}
}
Since Factory is inside T, it can access the private constructor, but outside code cannot. If you don't want to create a separate assembly, you could consider this approach.
Note that you could still put the factory class and T in two different files, with partial classes:
public partial class T {
private T() {}
// other stuff about T here...
}
// in another file
public partial class T {
public class Factory {
public T GetT() {
return new T();
}
// other stuff about Factory here...
}
}
public abstract class T { }
public class TFactory
{
public T CreateT() => new TImpl();
private class TImpl : T { }
}
The second approach is the worst one. That behavior is absolutely unobvious and unclear to a client. Stack tracing also slows down execution. The 1st and the 2nd make sense.
If you want to have total control of instance creation put it into the type. Use a factory method. Remember, one should be reasonable when putting constraint on instance creation. E.g. the instance should be initiated with a polymorphal (virtual) method. One can't call such a method from a constructor (a very bad practice), so the method should be called after construction. For not to put that responsibility on the client, hide the constructor from one and provide a factory method.
abstract class Base
{
protected abstract void Initialize();
}
class Derived : Base
{
protected Derived() { /* ... */}
protected override void Initialize() { /* ... */}
public Derived CreateDerived()
{
var derived = new Derived();
derived.Initialize();
return derived;
}
}
Related
I have interface and some classes that implement this interface.
I want to listen for any object that will be instantiated and check if this object implements my interface.
My primary reason is to store all references to this kind of objects and simply call a method of interface to all objects.
As Kyle said in the comments the constructor of an abstract class would be the best choice. Or a factory that must be used for construction of those kind of objects.
But if this is not an option maybe the following approach is acceptable in your case.
If the "listener" is globally accessible (e.g. something static) you can add methods like Register(IYourInterface obj) and Unregister(IYourInterface obj) to it and ensure that every class that implements the interface will call these methods on construction / deconstruction. Not the cleanest way, but it will work as long as you maintain this behavior.
Example:
public static class Listener
{
private static List<IMyInterface> objects = new List<IMyInterface>();
public static void Register(IMyInterface obj)
{
if (!objects.Contains(obj))
objects.Add(obj);
}
public static void Unregister(IMyInterface obj)
{
if (objects.Contains(obj)
objects.Remove(obj);
}
public static void DoSomethingWithObjects()
{
foreach (IMyInterface obj in objects)
// do something ...
}
}
public class SomeTestClass : IMyInterface
{
public SomeTestClass()
{
Listener.Register(this);
}
}
There are a few ways to go about this.
Use a base abstract class
Easiest solution is to have a base class that everything inherits from. This kind of defeats the purpose of the interface, but this is the only way you can add this sort of code for creation. You could do something like:
public abstract class AbstractBaseClass
{
public AbstractBaseClass()
{
ObjectRegister.StoreReference(this);
}
public abstract void MethodToCall();
}
public class SubClass : AbstractBaseClass
{
public SubClass() : base() //Don't forget 'base()'!
{
//Your code here
}
public override void MethodToCall()
{
Console.WriteLine("Called in SubClass");
}
}
The abstract MethodToCall could also be virtual if you want to provide a default action, but if it's abstract the compiler will complain that you haven't implemented it in a similar way to interfaces.
Use a public static instantiating method
A bit more verbose, but can be seen in things like Unity. In this case, instead of doing x = new Y(), you have a public static method, perhaps a generic one, that creates the class for you, registers it, then returns that instance. Assuming your interface is called 'IRegisterable', you could have something like:
public static class ObjectRegister
{
//Note the 'where', which constrains T to be something that
//implements IRegisterable
public static T Instantiate<T>() where T:IRegisterable
{
T obj = new T();
StoreReference(obj);
return obj;
}
private static StoreReference(IRegisterable obj)
{
//Do your storing code here. This doesn't even need to be a method
//if your reference storing stuff only happens on object creation
}
}
//Elsewhere, where class 'Thing' implements IRegisterable
Thing x = ObjectRegister.Instantiate<Thing>();
//x is now registered. No need to do x = new Thing()
string y = ObjectRegister.Instantiate<string>();
//Error: string does not implement IRegisterable
Unfortunately, supplying constructor arguments this way isn't easy. You could just have an Init() method though which acts as a sort of fake constructor.
I have an abstract super class and subclasses inheriting from it.
Each subclass MySubclass shall have a public static MySubclass CreateFrom(ISomething something) factory method. The interface of its argument is the same for all subclasses, but the return type must of course always be the type of the respective subclass.
Can I somehow achieve this to have static factory methods following an interface or abstract superclass method definition without creating a separate static factory class for each single subclass?
If the ISomething is always of the same (or at least a common) type, you could make the CreateFrom method of the superclass generic and Invoke the constructor of the inherited class with the parameter. Just make sure all your inherited classes have that constructor (Not sure but I don't think there is a way to 'force' a constructor pattern).
public abstract class SuperClass
{
public static T CreateFrom(ISomething something)
{
return (T)Activator.CreateInstance(typeof(T), something);
}
}
public class InheritedClass : SuperClass
{
public InheritedClass(ISomething something)
{}
}
This way you can create instances by calling
SuperClass.CreateFrom<InheritedClass>(something);
Or you split the creation and initialization:
public abstract class SuperClass
{
protected abstract void Initialize(ISomething something);
public static T CreateFrom(ISomething something) where T : new()
{
T result = new T();
T.Initialize(something);
}
}
public class InheritedClass : SuperClass
{
public InheritedClass()
{}
protected override Initialize(ISomething something)
{}
}
You can´t define static members on interfaces as static members belong to a certain class. However I can´t imagine of a reason to use this. You should ask yourself why you need such a functionality. Does a sub-class really have to instantiate itself or can the same easily be done with another independent (factory-)class?
Just create one simple factory-class with a generic parameter that indicates what to create.
class Factory<T> where T: new()
{
T CreateFrom(ISomething param)
{
return new T();
}
}
Now you can simply call it like this:
var myFactory = new Factory<MyClass>();
myFactory.CreateFrom(mySomething);
I resorted to a different solution in similiar kind of requirement. In my superclass which happened to be an abstract one I required to create an instance of subclass to do something with it so I did the following trick:
public abstract class Element
{
protected virtual void copyFrom(Element other)
{
}
protected abstract Elememt newInstanceOfMyType();
public object clone()
{
var instance= newInstanceOfMyType();
instance.copyFrom(this);
return instance;
}
}
Now all my subclasses inheriting from Element class required to override newInstanceOfMyType method to give away instance of its type and then also override copyFrom method to produce a perfect clone. Now people might argue that why an abstract Clone method cant do the same job? Yes it can. But I required cloned instance of subclass as well as an empty instance(without copying anything from current) so I came up with this architecture.
I faced with the code below
XmlReader xmlreader =
XmlReader.Create("http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml");
here to make a new object of XmlReader, it just used calling method of XmlReader.
I know here Create is a static method, but it is a little odd for me.
I used to exploit new word to command making new instance.
Can anyone please tell me how does this line works?
The method you're calling does it for you:
public class XmlReader {
public static XmlReader Create(String url) {
// There's probably a lot of fancy code in this method, but it'll use new somewhere
return new XmlReader(...);
}
}
(It's possible to avoid new altogether by using a technique called reflection, but that's not what's going on here.)
This is an example of a factory method. (Which can often be a step toward using a separate factory object.)
Somewhere in XmlReader.Create it is internally making use of the new keyword. In order to instantiate a new instance of an object, you need to use new to call a constructor. To reduce coupling between objects, however, you may abstract that behind a factory method or factory object.
For example, these two implementations do roughly the same thing:
public class Widget
{
public Widget() { }
}
//... elsewhere ...
var widget = new Widget();
And:
public class Widget
{
private Widget() { }
public static Widget Create()
{
return new Widget();
}
}
//... elsewhere ...
var widget = Widget.Create();
In an example this simple, there's little difference between the two. As code evolves and becomes more complex, there can be a number of compelling reasons to choose one over the other. For example:
There are complex constructors and you want to expose a simple interface for building an instance.
The constructors are likely to change often and you want consumers of your library to have a single unchanging interface.
There is significant logic invoked when building an object and you want to move that logic to its own object.
You want to use a separate object for mockability in automated testing.
You have a more complex inheritance structure and want to expose a top-level abstract factory.
etc.
It's a static method that, in it's body, creates a new object (using new) and returns it.
You can emulate the pattern like so:
public class Foo
{
public static Foo Create()
{
return new Foo();
}
}
public class Foo
{
public string Prop { get;set; }
public Foo(string prop)
{
Prop = prop;
}
public static Foo Create(string prop)
{
return new Foo(prop);
}
}
This is how it can look like under.
There are several reasons to create factory Methods. Do you want control about all the Instances created of a Type? For example you could do something like that:
public class MyClass {
private MyClass() // private constructor optional
{}
public void Create()
{
return new MyClass();
}
}
(private constructors are often used to implement the Singleton Pattern)
Factory Methods could also be in a seperate Class.
public class MyClass {
internal MyClass() // means only Classes of same assembly may access this
{}
}
public class MyClassFactory {
public void NewMyClass()
{
// Do some license checking here or whatever
return new MyClass();
}
}
Factory Methods define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
Read more about Factory Methods here.
I have a factory object ChallengeManager to generate instances of a Challenge object for a game I'm building. There are many challenges. The constructors for each Challenge class derivation are different, however there is a common interface among them, defined in the base class.
When I call manager.CreateChallenge(), it returns an instance of Challenge, which is one of the derived types.
Ideally, I would like to keep the code for the object construction inside the derived class itself, so all the code related to that object is co-located. Example:
class Challenge {}
class ChallengeA : Challenge {
public static Challenge MakeChallenge() {
return new ChallengeA();
}
}
class ChallengeB : Challenge {
public static Challenge MakeChallenge() {
return new ChallengeB();
}
}
Now, my ChallengeManager.CreateChallenge() call only needs to decide the class to call MakeChallenge() on. The implementation of the construction is contained by the class itself.
Using this paradigm, every derived class must define a static MakeChallenge() method. However, since the method is a static one, I am not able to make use of an Interface here, requiring it.
It's not a big deal, since I can easily remember to add the correct method signature to each derived class. However, I am wondering if there is a more elegant design I should consider.
I really like the pattern you are describing and use it often. The way I like to do it is:
abstract class Challenge
{
private Challenge() {}
private class ChallengeA : Challenge
{
public ChallengeA() { ... }
}
private class ChallengeB : Challenge
{
public ChallengeB() { ... }
}
public static Challenge MakeA()
{
return new ChallengeA();
}
public static Challenge MakeB()
{
return new ChallengeB();
}
}
This pattern has many nice properties. No one can make a new Challenge because it is abstract. No one can make a derived class because Challenge's default ctor is private. No one can get at ChallengeA or ChallengeB because they are private. You define the interface to Challenge and that is the only interface that the client needs to understand.
When the client wants an A, they ask Challenge for one, and they get it. They don't need to worry about the fact that behind the scenes, A is implemented by ChallengeA. They just get a Challenge that they can use.
You're "decentralizing" the factory, such that each subclass is responsible for creating itself.
More commonly you would have a central factory that would know about the possible subtypes and how to construct them (often enough, simply by creating a new instance and returning that instance typed as a common interface or common base class). That approach avoids the issue you currently have. I also see no benefit to your current approach. You are currently gaining no encapsulation or code reuse over the more typical implementation of a factory.
For additional reference, have a look at
http://www.oodesign.com/factory-pattern.html
Not necessarily the answer you are looking for but...
You can use following implementation, if you can move away from static method per class.
using System;
public class Test
{
public static void Main()
{
var c1 = ChallengeManager.CreateChallenge();
var c2 = ChallengeManager.CreateChallenge();
//var c = ChallengeManager.CreateChallenge<Challenage>(); // This statement won't compile
}
}
public class ChallengeManager
{
public static Challenage CreateChallenge()
{
// identify which challenge to instantiate. e.g. Challenage1
var c = CreateChallenge<Challenage1>();
return c;
}
private static Challenage CreateChallenge<T>() where T: Challenage, new()
{
return new T();
}
}
public abstract class Challenage{}
public class Challenage1: Challenage{}
public class Challenage2: Challenage{}
I have an asbtract class Example. Another generic class UsesExample uses it as a constraint, with a new() constraint. Later, I create a child to Example class, ExampleChild, and use it with generic class. But somehow when the code in generic class tries to create new copy, it invokes not the constructor in the child class, but the constructor in the parent class. Why does it happen?
Here's the code:
abstract class Example {
public Example() {
throw new NotImplementedException ("You must implement it in the subclass!");
}
}
class ExampleChild : Example {
public ExampleChild() {
// here's the code that I want to be invoken
}
}
class UsesExample<T> where T : Example, new() {
public doStuff() {
new T();
}
}
class MainClass {
public static void Main(string[] args) {
UsesExample<ExampleChild> worker = new UsesExample<ExampleChild>();
worker.doStuff();
}
}
When you crate an object, all constructors are called. At first the base class constructor constructs the object so that the base members are initialized. Later the others constructors in hierarchy are called.
This initialization may call static functions so that it makes sense to call the constructor of an abstract base class event if it has no data members.
Whenever you create a new instance of a derived class, the base class's constructor is called implicitly. In your code,
public ExampleChild() {
// here's the code that I want to be invoked
}
is really turned into:
public ExampleChild() : base() {
// here's the code that I want to be invoked
}
by the compiler.
You can read more on Jon Skeet's detailed blog post on C# constructors.
In a derived class, if a base-class constructor is not called explicitly using the base keyword, then the default constructor, if there is one, is called implicitly.
from msdn
also, you can read here