In general, if constucting an object is simple (like you have shown) then providing appropriate constructors is fine. If construction is even a little more complex (maybe you have to look something up in a database, maybe you need some conditional logic,
maybe you need to call a service) then you would be better off using a factory method. A factory method is a static method in another class (the 'factory') which knows how to make objects. It's signature might be something like
public static Customer MakePreferred(int id, string name, double last12MonthsSpend)
This factory method might use the last12MonthsSpend in some complex logic to determine the appropriate amount of credit available to the customer and return a Customer object with the appropriate values set.
Think about a real world car and how you would model it in software. There would be all sorts of methods to 'Accelerate', 'IndicateTurn', 'ReceiveFuel' and so on. These are all things that real cars do. One thing that a real car does not do is construct
itself. Construction of real cars is a specialised activity which is done in a factory. It makes sense for a Car object in a program to also be constructed in a factory.
The constructor in your original post is wrong. You have assigned internal fields to the parameters (Id = _id) which is back to front. The purpose of the constructor is to build a Customer by using information that has been passed to it. The body of the
constructor should be
this.ID = Id;
(using 'this' is not really required but makes it clear that the left hand side is a property of the instance being constructed)
Also, get rid of a lot of your code. For example the property ID can just be
public int ID {get; set;}
and now you can delete the _id field.
The same optimisation can be done for Name and Amount
By the way, don't yell - NAME and AMOUNT. All uppercase is associated with a different convention.
It's a matter of style but I would have the Age property throw an exception if the value does not meet your requirements (I notice that you allow negative ages but not an age of 100, which is a little odd). The callers who are setting the property should
pass legal values and should deal with any problems that arise themselves. What if Customer is used by a client which does not have a visual interface? The way that your code is written you have to assume a lot about the environment that has called you.
What colours (style in general) should the messgae use? Is the client a console application, WinForms, WPF, Silerlight, WebForms, MVC, a web service or ...? Much better to let the client deal with any problems in a manner which is best for that client.
Paul Linton
Star
13421 Points
2535 Posts
Re: It is the right way to do so: Constructor
Jan 31, 2012 08:44 PM|LINK
In general, if constucting an object is simple (like you have shown) then providing appropriate constructors is fine. If construction is even a little more complex (maybe you have to look something up in a database, maybe you need some conditional logic, maybe you need to call a service) then you would be better off using a factory method. A factory method is a static method in another class (the 'factory') which knows how to make objects. It's signature might be something like
public static Customer MakePreferred(int id, string name, double last12MonthsSpend)
This factory method might use the last12MonthsSpend in some complex logic to determine the appropriate amount of credit available to the customer and return a Customer object with the appropriate values set.
Think about a real world car and how you would model it in software. There would be all sorts of methods to 'Accelerate', 'IndicateTurn', 'ReceiveFuel' and so on. These are all things that real cars do. One thing that a real car does not do is construct itself. Construction of real cars is a specialised activity which is done in a factory. It makes sense for a Car object in a program to also be constructed in a factory.
Have a look at http://www.udidahan.com/2009/06/29/dont-create-aggregate-roots/ It may be a too advanced for where you are at in learning to program but it may open your eyes to some of the concepts that the best developers think about.
The constructor in your original post is wrong. You have assigned internal fields to the parameters (Id = _id) which is back to front. The purpose of the constructor is to build a Customer by using information that has been passed to it. The body of the constructor should be
this.ID = Id;
(using 'this' is not really required but makes it clear that the left hand side is a property of the instance being constructed)
Also, get rid of a lot of your code. For example the property ID can just be
public int ID {get; set;}
and now you can delete the _id field.
The same optimisation can be done for Name and Amount
By the way, don't yell - NAME and AMOUNT. All uppercase is associated with a different convention.
It's a matter of style but I would have the Age property throw an exception if the value does not meet your requirements (I notice that you allow negative ages but not an age of 100, which is a little odd). The callers who are setting the property should pass legal values and should deal with any problems that arise themselves. What if Customer is used by a client which does not have a visual interface? The way that your code is written you have to assume a lot about the environment that has called you. What colours (style in general) should the messgae use? Is the client a console application, WinForms, WPF, Silerlight, WebForms, MVC, a web service or ...? Much better to let the client deal with any problems in a manner which is best for that client.