Reading some article about singleton, I stopped at the point saying: "Do not allow to crate copy of existing instance".
I realized that I do not know how would I do that! Could you tell me, please, how could I copy existing instance of class?
And the second one: deserializaition. How it could be dangerous?
And for both - how to deny creating copies or deserialization?
Thanks
There are objects with something like a Clone or a Copy method. The idea behind it that it will take the current values of the object and make a new one. The defeats the purpose of a singleton object, because suddenly someone can create a second copy of it.
Another possible way of creating a copy of the object, would be to serialize the object and then de-serialize it to create another copy. So you probably want to mark the singleton object as not serializable.
Using serialization/deserialization, you could store the object somewhere and then restore it. That way, you will have two objects. Any changes made to the singleton in the meantime would not be reflected in your new copy.
Afterwards, when you now try to get/set something using the singleton object, you might change it in/get it from the one object or the other. Obviously that can cause all sorts of (sometimes very hard to debug) problems.
EDIT: To create a singleton in C#, see the explanation at http://www.yoda.arachsys.com/csharp/singleton.html
As for serialization: You have to explicitely enable it by including the SerializableAttribute. So simply don't mark your class with it. Note that there is no NonSerializableAttribute for classes, only for fields. It is used when you enabled serialization, but want to deny it for certain parts of the class.
EDIT2: To deny XML-serialization, you could implement IXmlSerializable on the class. Then simply either have empty implementations or throw exceptions from the member methods.
As has already been mentioned:
You don't want to make a singleton serializable or copy/clone-able because then you can make more than one object, which defeats the purpose of the singleton.
To prevent serialization in c# is easy - don't mark the class as [Serializable]
To prevent copying/cloning of your singleton you could try changing it to a static class so that can't be instantiated (in the normal way) if that's practical. I'm not sure if the class is technically a singleton any more then.
Another way (probably better) is detailed in Item 13 of Bill Wagner's Effective C#. i.e. using a static constructor and making your singleton a read only property of your static class.
Example:
public class SingletonExample
{
private static readonly SingletonExample singleInstance
static SingletonExample()
{
singleInstance = new SingletonExample();
}
public static SingletonExample Instance
{
get { return singleInstance; }
}
private SingletonExample()
{
}
}
There are a few things to look out for, like Kevin mentioned any sort of .Clone() or .Copy() methods. If your building the class your self, then be carful with the .MemberwiseClone() method as it will make shallow copies of the object.
As far as serialization. Preventing general serialization can be done by not tagging [SerializableAttribute()] to you class. I'm not sure there is a way to prevent XmlSerialzation, directly. But there are a few things you could do to prevent this if your building the class.
If you're building the class, and you do not provide a default constructor then the XmlDeserializer will not work as it uses the default constructor to rebuild the object. I belive this funcitonality has changed in 4.0 however, so you may want to look more into that. Using the [XmlIgnore] Attribute on yoru fields and properties will render the serialzation useless as well.
The important part here is that the person trying to do this understand it shouldn't be done, not that it can't. If someone really wants to do serialization/deserialization on your class, then you can't stop all avenues as he can implement his own serialzation/deserialization of your object. Also serialzation of singletons is sometimes intended such as the cases of application settings or custom settings. The intent is to inform somehow the person trying to serialize/deserialize not to do so.
Related
A pattern I occasionally see is like this:
public class JustAnotherClass
{
private JustAnotherClass()
{
// do something
}
static JustAnotherClass GetNewClass()
{
return new JustAnotherClass();
}
}
Why would this ever give an advantage over just having a public constructor?
Why would this ever give an advantage over just having a public constructor?
It's a factory pattern. You have a single point where these instances are made.
The advantage would be that in a future extension you could add logic, like returning a derived class instance. Or to return null under certain conditions. A constructor cannot return null.
Good question. The class you show is a factory (see factory pattern). So 'why use a factory' ... as I said a good question.
For me, I use factories when I need to create instances at run time (many times). Why? Because it makes my code some much easier to test using unit testing. This is one answer to you question and it is irrelevant if you do not unit test (and perhaps TDD) your code. No wrongs or rights here, just a fact.
To answer you question ask 'why use a factory'.
Besides from being for flexible, you need this approach if you want to use parameters in your constructor (at least this behavior) and XML serialization at the same time.
I don't see any advantage of having a static method just to create a new object. It is more or less equvalent to directly call constructor.
it makes code more scaleable which won't be possible with public constructor. Check Henk holterman's answer also.
It can return a derived class.
Sometimes you have different internal implementations of a base class, and the consumer shouldn't know which one he got, since it's an implementation detail.
It has a name.
I often use it instead of overloading the constructor, so it becomes clearer what the meaning of this new instance is.
One example from a recent project of me: I have a class representing an asymmetric key-pair. The constructor is protected and there are two factory methods: FromPrivateKey(byte[]) and GenerateIdentity(). IMO this makes consuming code easier to read.
As it is in your example there's no real advantage. You use a factory method when you want to control when and how instances of your class are created. Some examples:
You want to implement a Singleton, that is always return the same instance;
You want to implement a cache and ensure that new instances are created only when no existing instance is available;
You need to control when instances are created based on external information. For instance you might be mapping the file system and want to ensure that no two instances of your File class exist for the same pathname.
i want to write my own serialisation (xml and binary do not fit for me,
i want "a more ADO" way)
so i defined an interface:
interface ISerializeData
{
DataTable GetDataSchema();
DataTable SerializeData();
object DeserializeData(DataTable data);
}
now i do not want to create an instance of an object to let
me get the schema for that object.
And: DeserializeData should return an instance, not use an instance.
Therefore i think it should be also static. (okay, it can initialize
an instancce from a datatable...)
Any ideas? How can i model that? static is not allowed in
interfaces and my classes already inherit from another abstract
base class.
Any ideas appreciated!
that issue is why the other serializer utilize attributes as they allow you to provide metadata about how the class is to be stored with out forcing you to deal with the implementation of the class itself.
Maybe I'm wrong, but this is really more a task for a utility class. Take DeserializeData, for instance. Somewhere in your code you decide which type you're going to construct. In your proposed code you would choose the type and call its static method. Now what? Would each type have its own code to do the serialization? You'd probably end up creating some class doing all the work, to stay DRY. So you might as well have one DeserializeData method in a utility class, like:
public static T DeserializeData(DataTable data)
where T : new
{
var T = new T();
.... // Set properties
}
In this method you'd probably get the data schema.
Maybe SerializeData() could be an instance method, but that too would delegate its work to some utilty class.
Please let me know if I completely misunderstood your question.
I'd like to get some feedback on what people think of the following class construction techniques.
If I'm in a situation where I have the choice of using either of the following:
Initialise an object completely in the constructor,
Initialise an object by way of it's public properties after the instance has been created.
[removed blogspam]
Wherever possible (and appropriate), create object instances in a usable state. (so No. 1)
I agree with Mitch, but sometimes there's more to it.
A Factory approach can make your code cleaner, easier to use and maintain. In some ways they aren't much more than glorified constructors but they do give you extra flexibility.
The factory methods can be given names that match their case of use.
Callers only need to supply the parameters required. Admittedly you can also do this for 'normal' constructors but it's clearer to the caller why they should use a given constructor if it also has an appropriate name.
Moving all complex code out of the constructors makes your code easier to maintain.
Using a Full blown Factory (one that returns an abstract class / interface) gives you some abstraction from the concrete class itself.
Examples:
// Typlical constructor
public Page(pageId, title, url, keywords, content, tags, lastModified, lastModifiedBy)
{
// All values are set via the constructor.
//...
}
Factory methods:
public static Page PageByID(pageId)
{
// All properties are set internally here
//(directly or delegated as appropriate).
//...
}
public static Page NewPage(title, url)
{
// All properties not passed in are given
// appropriate default values.
//...
}
public static Page Page404()
{
// All properties are given
// appropriate default values.
//...
}
As Mitch said, normally you'd create an object through a constructor that would at least put it in a stable state. You can use public properties later to set non-critical properties of the object.
However, sometimes you don't really have a choice. A framework might require a default constructor (without parameters). In that case you'll need to get the object in a stable state in another way. Using public properties is possible, but it would be easy to forget something. In these cases I'd advise creating an Initialize (or similar) method that you call directly after the object has been created. This method can then require you to fill in all the needed parameters for a stable state so you can't forget anything. The difference is that you can't really force calling this method unless you keep internal 'isInitialized' state that you check in each public member.
Edit: ah just saw the post about the factory. Yes, of course, in case of a framework requiring default constructors you could also get a factory back and call the methods on that.
public MyClass(int someUniqueID)
{
using(//Session logic)
{
var databaseVersionOfMyClass = session.CreateCriteria(/*criteria*/)
.UniqueResult<MyClass>();
//Load logic
}
}
The code sample above is my current direction, although I've reached a point where I need a bit of a sanity check.
With NHibernate(I'm green in this area), is it common or best practice to instantiate an object from a database within the class constructor? The alternative I believe, would be to have a static method that returns the object from the database.
I've also come across a relevent question regarding constructors vs factory methods, however I don't believe this implementation fits the factory methodology.
To add an additional question onto the above, if instantiation within the constructor is the way to go, I've always used some sort of Load() method in the past. Either a specific private method that literally matches properties from the returned db object to the new class, or via a generic reflective method that assumes property names will match up. I'm curious if there is another way to "load" an object that I've missed.
I do not like this approach.
IMHO , it is better to implement some kind of repository which retrieves instances of persisted classes for you.
As an alternative, you could also follow the ActiveRecord approach, where you could have a static 'Load' method inside your class, and an instance method 'Save' for instance. (Take a look at Castle ActiveRecord).
But, for me, I prefer the Repository approach.
I have an initialization class that preloads content into a variable (probably a list or array). There will only be one instance of this initialization class but there will be many classes that need to access the preloaded content.
The problem is not many of them are related and none of them extend my initialization class. I thought about this for a bit and decided on using a static method and variable for this use. So something like this...
public class InitClass
{
static List PreloadedContent;
static ModelData GetContent(String ContentName)
{
//return the preloaded content that matches given name
}
}
The preloaded content may at some time decrease or increase in size depending on what the situation may call for. I've run into situations where something like this has been the only decent looking solution however; I think its an ugly solution.
Note: I can't load the data onto a class that needs it when it is created due to a variety of reasons - most of which are reasons I don't know about yet but will most likely come up. Certain classes will be loaded/unloaded depending on the rendering of the scene and my InitClass won't handle the creation of these objects most of the time.
Can anyone give me a better solution?
what you are doing is known as singleton. here are some previous discussions on this:
How to implement a singleton in C#
What’s a good threadsafe singleton generic template pattern in C#
To avoid static/global scope you could use some kind of Registry class. This means you have one class which you initialize at program startup. This class holds references to all other classes that need to be accessed globally.
Now you pass the initialized instance of your registry class to all instances in your application.
It isn't a very pretty soluation, but for me it is the best. With Static and global variables I always ended up in having some problems when testing or debugging code.
Another aproach would be to use a Singleton. Since they also just hold a static instance I would not prefer them.