Class Construction Techniques - c#

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.

Related

Passing a custom attribute with a variable value as a parameter

I created a custom attribute class that will check the system security and throws an authentication exception if there is a security error.
public class EntityChecker: System.Attribute
{
public EntityChecker(int entityId)
{
// doing some logic to check if the entityId is allowed to be inserted
}
}
I want to use this custom attribute as a declaration to an entity addition function and I want to pass a variable from the function to the attribute constructor. can something like this be done?
[EntityChecker(entityId)]
public int AddNewEntity(entityId)
{
// logic of entity addition
}
Can something like this be done ?!
No. Constructor parameters in attributes must be resolved at compile time. They are intended as metadata on the type or method itself, not something that would be used per call or per instance.
Given your description, an attribute is likely not an appropriate way to handle this. Since you want to run extra code that happens per call, you will need a different technique. For example, you could pass a delegate, ie:
public int CheckedAddEntity(int entityId, Func<int, int> funcToAdd)
{
// Perform your checking on entityId here
return funcToAdd();
}
This would let you then call via something like:
int result = CheckedAddEntity(entityId, AddNewEntity);
In this case, I recommend looking at Aspect-Oriented programming. It is a different way of doing code, but one that allows you to re-use the boilerplate logic (e.g. authentication) throughout. You might have to design your attribute a little bit differently, but all of the logic can be put into an "aspect" which then gets compiled automatically into the code when you build the project.
I personally use PostSharp, although I know there are others out there. They have a free license available for development; as long as you don't require advanced functionality, it's very cost-effective.
http://www.postsharp.net/blog/post/5-Ways-That-Postsharp-Can-SOLIDify-Your-Code-Authorization

Is there an advantage to using a static method which returns a new instance via a private constructor?

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.

Constructing a (somewhat) complex object

When I create classes, simple constructors tend to be the norm. On one of my current projects, a movie library, I have a Movie domain object. It has a number of properties, resulting in a constructor as follows:
public Movie(string title, int year, Genre genre, int length, IEnumerable<string> actors)
{
_title = title;
_year = year;
_genre = genre;
_length = length;
_actors = new List<string>(actors);
}
This isn't terrible, but it's not simple either. Would it be worthwhile to use a factory method (static Movie CreateMovie(...)), or a perhaps an object builder? Is there any typical pattern for instantiating domain classes?
UPDATE: thanks for the responses. I was probably overthinking the matter initially, though I've learned a few things that will be useful in more complex situations. My solution now is to have the title as the only required parameter, and the rest as named/optional parameters. This seems the all round ideal way to construct this domain object.
If you are using .NET 4.0, you can use optional/named parameters to simplify the creation of an object that accepts multiple arguments, some of which are optional. This is helpful when you want to avoid many different overloads to supply the necessary information about the object.
If you're not on .NET 4, you may want to use the Object Builder pattern to assembly your type. Object builder takes a bit of effort to implement, and keep in sync with you type - so whether there's enough value in doing so depends on your situation.
I find the builder pattern to be most effective when assembling hierarchies, rather than a type with a bunch of properties. In the latter case, I generally either overloads or optional/named parameters.
Yes, using a factory method is a typical pattern, but the question is: Why do you need it? This is what Wikipedia says about Factory Methods:
Like other creational patterns, it deals with the problem of creating objects (products) without specifying the exact class of object that will be created. The factory method design pattern handles this problem by defining a separate method for creating the objects, which subclasses can then override to specify the derived type of product that will be created.
So, the factory method pattern would make sense if you want to return subclasses of Movie. If this isn't (and won't be) a requirement, replacing the public constructor with a factory method doesn't really serve any purpose.
For the requirements stated in your question, your solution looks really fine to me: All mandatory fields are passed as parameters to the constructor. If none of your fields are mandatory, you might want to add a default initializer and use the C# object initializer syntax.
It depends.
If that is the only constructor for that class, it means all the properties are required in order to instantiate the object. If that aligns with your business rules, great. If not, it might be a little cumbersome. If, for example, you wanted to seed your system with Movies but didn't always have the Actors, you could find yourself in a pickle.
The CreateMovie() method you mention is another option, in case you have a need to separate the internal constructor from the act of creating a Movie instance.
You have many options available to your for arranging constructors. Use the ones that allow you to design your system with no smells and lots of principles (DRY, YAGNI, SRP.)
I don't see anything wrong with your constructor's interface and don't see what a static method will get you. I will have the exact same parameters, right?
The parameters don't seem optional, so there isn't a way to provide an overload with fewer or
use optional parameters.
From the point-of-view of the caller, it looks something like this:
Movie m = new Movie("Inception", 2010, Genre.Drama, 150, actors);
The purpose of a factory is to provide you a customizable concrete instance of an interface, not just call the constructor for you. The idea is that the exact class is not hard-coded at the point of construction. Is this really better?
Movie m = Movie.Create("Inception", 2010, Genre.Drama, 150, actors);
It seems pretty much the same to me. The only thing better is if Create() returned other concrete classes than Movie.
One thing to think about is how to improve this so that calling code is easy to understand. The most obvious problem to me is that it isn't obvious what the 150 means without looking at the code for Movie. There are a few ways to improve that if you wanted to:
Use a type for movie length and construct that type inline new MovieLength(150)
Use named parameters if you are using .NET 4.0
(see #Heinzi's answer) use Object Initializers
Use a fluent interface
With a fluent interface, your call would look like
Movie m = new Movie("Inception").
MadeIn(2010).
InGenre(Genre.Drama).
WithRuntimeLength(150).
WithActors(actors);
Frankly, all of this seems like overkill for your case. Named parameters are reasonable if you are using .NET 4.0, because they aren't that much more code and would improve the code at the caller.
You gave a good answer to your own question, it's the factory pattern. With the factory pattern you don't need huge constructors for encapsulation, you can set the object's members in your factory function and return that object.
This is perfectly acceptable, IMHO. I know static methods are sometimes frowned upon, but I typically drop that code into a static method that returns an instance of the class. I typically only do that for objects that are permitted to have null values.
If the values of the object can't be null, add them as parameters to the constructor so you don't get any invalid objects floating around.
I see nothing wrong with leaving the public constructor the way it is. Here are some of the rules I tend follow when deciding whether to go with a factory method.
Do use a factory method when initialization requires a complex algorithm.
Do use a factory method when initialization requires an IO bound operation.
Do use a factory method when initialization may throw an exception that cannot be guarded against at development time.
Do use a factory method when extra verbage may be warranted to enhance the readability.
So based on my own personal rules I would leave the constructor the way it is.
If you can distinguish core data members from configuration parameters, make a constructor that takes all of the core data members and nothing else (not even configuration parameters with default values—shoot for readability). Initialize the configuration parameters to sane default values (in the body of the method) and provide setters. At that point, a factory method could buy you something, if there are common configurations of your object that you want.
Better yet, if you find you have an object that takes a huge list of parameters, the object may be too fat. You have smelled the fact that your code may need to be refactored. Consider decomposing your object. The good literature on OO strongly argues for small objects (e.g. Martin Fowler, Refactoring; Bob Martin, Clean Code). Fowler explain how to decompose large objects. For example, the configuration parameters (if any) may indicate the need for more polymorphism, especially if they are booleans or enumerations (refactoring "Convert Conditional to Polymorphism").
I would need to see the way that your object is used before giving more specific advice. Fowler says that variables that are used together should be made into their own object. So, sake of illustration, if you are calculating certain things on the basis of the genre, year and length, but not the other attributes, those together may need to be broken out in to their own object—reducing the number of parameters that must be passed to your constructor.
As for me - all depending on your domain model. If your domain model allows you to create simple objects - you should do it.
But often we have a lot of composite objects and the creation of each individually is too complicated. That's why we`re looking for the best way to encapsulate the logic of composite object creation. Actually, we have only two alternatives described above - "Factory Method" and "Object Builder". Creating object through the static method looks a bit strange because we placing the object creation logic into the object. Object Builder, in turn, looks to complicated.
I think that the answer lies in the unit tests. This is exactly the case when TDD would be quite useful - we make our domain model step-by-step and understand the need of domain model complexity.

C# Is there any benefit to assigning class properties in the class constructor?

For instance, if I have a class like this:
namespace Sample
{
public Class TestObject
{
private Object MyAwesomeObject = new MyAwesomeObject();
}
}
Is there any benefit to set it up so that the property is set in the constructor like this?
namespace Sample
{
public Class TestObject
{
private Object MyAwesomeObject;
public TestObject()
{
MyAwesomeObject = new MyAwesomeObject()
}
}
}
The two are (nearly) identical.
When you define the initializer inline:
private Object MyAwesomeObject = new MyAwesomeObject();
This will happen prior to the class constructor code. This is often nicer, but does have a couple of limitations.
Setting it up in the constructor lets you use constructor parameters to initialize your members. Often, this is required in order to get more information into your class members.
Also, when you setup values in your constructors, you can use your class data in a static context, which is not possible to do with inlined methods. For example, if you want to initialize something using an expression tree, this often needs to be in a constructor, since the expression tree is in a static context, which will not be allowed to access your class members in an inlined member initializer.
It makes it easier to do step by step debugging
It makes it easier to control the order in which you call constructors
It makes it possible to send parameters to the constructors based on some logic or passed in argument to the object you are working on.
Another nice property of initializing stuff at the declaration site is that doing so on readonly fields guarantees that the field is not observable in its default (initiaized to zero) state.
Here's my article on the subject:
http://blogs.msdn.com/ericlippert/archive/2008/02/18/why-do-initializers-run-in-the-opposite-order-as-constructors-part-two.aspx
The only benefit is that you can be a bit more dynamic in the constructor, where inline initialization requires that you only use static values for constructor arguments and such. For example, if MyAwesomeObject needs the value from a config file, you would have to set that in the constructor
Fields are initialized immediately
before the constructor for the object
instance is called. If the constructor
assigns the value of a field, it will
overwrite any value given during field
declaration.
See Fields (C# Programming Guide).
In your particular example, there's no advantage.
There is, however, lazy instantiation, which reduces your memory footprint in many cases:
namespace Sample
{
public Class TestObject
{
private Object m_MyAwesomeObject;
public TestObject()
{
}
public Object MyAwesomeObject
{
get
{
if (m_MyAwesomeObject == null)
m_MyAwesomeObject = new Object();
return m_MyAwesomeObject;
}
}
}
}
I like to keep all initialization for any class property whether primitive or object in the class constructor(s). Keeps the code easier to read. Easier to debug. Plus the intention of a constructor is to initialize your classes properties.
Also for clients developing against your classes it's nice to make sure that all your properties get a default value and all objects get created. Avoids the NullReferenceExceptions, when a client is using your class. For me putting this all in constructors makes it easier to manage.
I do not like to duplicate code, even if it is among a (hopefully) small number of constructors. To that end I tend to favor inline initialization wherever it makes sense.
Generally, requiring a non-default constructor ensures that the instance is in something other than the default state. This also allows immutable classes, which have their own advantages.

DAL Design/Load methods with NHibernate

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.

Categories