Constructing a (somewhat) complex object - c#

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.

Related

Ninject (IoC) and an alternative to a factory with conditional logic

I have run into a scenario that I would like to solve with Ninject but up until this point none of my work with it has cross this type of situation.
WCF Service App
W3C Log Parsing App (overly simplistic for demonstration purposes).
IW3CLogItem implemented by W3CLogItem
W3CLogItem has a public member of type IUrlData (contains the important data but can be one of 5 concrete implementations depending on what it contains).
The decision of which concrete implementation to use is based off of a string match and its constructor takes a regex pattern it will use to parse the data as well as the string to be parsed.
Currently I have a simple factory that does the string comparisons and then calls Create() to return a new concrete object (DocumentUrlItem, DriverUrlItem, AssetUrlItem, etc...).
I was looking at the wiki docs and how to name a binding, but even that only gets me half of the way.
The question I have is: Can this be done without a factory? Can I somehow place a conditional attribute on a binding (i.e. .contains, etc...) that evaluates to true to know which binding to use or am I better off sticking with the factory?
Let elaborate a bit.
If I were to write the factory without ninject in a simplified way, it would look like this:
protected IUrlData Create(string urldata)
{
if (urldata.Contains("bob"))
{
return new BobUrlData(urldata)
}
else if (urldata.Contains("tim"))
{
return new TimUrlData(urldata);
}
}
A couple of things of note:
1) The number of classes that implement IUrlData will grow over time. The strings "tim", and "bob" will be coming from a database.
2) The urldata being passed into BobUrlData and TimUrlData is not the only parameter in the real world, there will also be a regular expression (also sourced from the database which is calculated by the entries timestamp that knows how to handle that particular entry as they have evolved over time.
3) I am really curious if this can be accomplished with Ninject without the need for the factory all together, to somehow through metadata or names achieve the same work but all through bindings all while leaving the code extensible but read-only (other than the binding modules).
You are able to bind to methods with Ninject.
Ninject Wiki - Contextual Binding
You shouldn't need the factory anymore if you set up the method to return what you need. I can't say one is better than the other though since they both work, but I do prefer the factory doing the work and having that access Ninject to give me the correct implementation. Your result is still the same in the end.
Also, right above on the same page is Specifying Constraints.
from a purist point of view, an abstract factory is the correct way to abstract out the implementation from the interface of an object. with that said, ninject offers various ways of implementing what you want without using an abstract factory. The ones that I feel will help you most are ToMethod and providers

Is there a pattern where you have a class whose job it is to instantiate common implementations of another class?

I want to call it a "Helper" but this seems way too general.
Let's say I have a class called WidgetCranker and WidgetCranker can be set up to crank out widgets of the type Square, Keyhole and GearShape. I can also specify which Color I want my widgets to be and which Label I want stamped on them.
Now, setting up each individual instance of WidgetCranker is fairly involved, the constructor just gives you an empty WidgetCranker and you have to manually set the type and colour of widgets you want to crank.
WidgetCranker keyholeWidget = new WidgetCranker();
keyholeWidget.Type = WidgetTypes.Keyhole;
keyholeWidget.Color = WidgetColors.Red;
keyholeWidget.Label = "ACME Industries Prototype 1";
But I have a class that requires a lot of WidgetCrankers that pretty much all look the same except for the label. I want to make my code more readable and less laborious to maintain, so I create a helper class that does all the lifting for me. So the above now becomes:
WidgetCranker keyholeWidget = WidgetCrankerHelper.RedKeyhole("ACME Industries Prototype 1");
My question is twofold:
Is this an actual design pattern and if so, what do we call it? I want to call it a factory, but it most definitely isn't a factory pattern. We're creating exactly the same kind of object in every case, just instantiating them differently. I know it's a type of "Helper", but I want to be more specific than that if I can. It's a helper that does a very specific thing.
Given that "Helper" is a very generic name, I feel that just naming the method by what it produces isn't enough. I should name it so that it's obvious what it does. So would MakeRedKeyhole be better or BuildRedKeyhole? I don't want to use GetRedKeyhole because that implies we're getting back a reference to an existing instance and not creating a brand new one.
I tend to stay away from the term "Helper" as all classes are supposed to be helpful, right? :)
I think that calling this either Factory or Builder would be acceptable. The point of abstract factory is to encapsulate the construction/instantiation of an object. It could return different types, but it doesn't need to. The type consuming the factory shouldn't care.
I tend to use the "Builder" name when it is doing any complex construction like this.

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.

Assigning "Actions" to objects

I'm developing a library in which I have two groups of classes:
A) a couple of classes with a bunch of functions, or "actions", already written in code
B) a few classes which must be "configured" when instantiated, in a way that the user using my library can instantiate objects from this second group of classes and "assign" actions from the first group
Right now I'm using delegates, like this:
Somwhere in the code I declare some delegates that are used by A and B:
public delegate void Action03(int value);
Then I have the "actions" implemented in the group A:
public Delegates.Action03 DoSomething03 = delegate(int value) { [code to execute when this action is specified on the constructor] };
And finally we use constructors like the following to instantiate objects from group B, where we pass as arguments the delegates/actions that we want:
public SomethingGroupB(Delegates.Action03 act03) { ... }
So of course, we can instantiate objects passing delegates as arguments:
SomethingGroupB somthg1 = new SomethingGroupB(GrpA01.DoSomething03);
But the whole point is that we can instantiate similar objects but assigning different actions:
SomethingGroupB somthg2 = new SomethingGroupB(GrpA07.DoSomething03);
SomethingGroupB somthg3 = new SomethingGroupB(GrpA01.DoSomething01);
SomethingGroupB somthg4 = new SomethingGroupB(GrpA02.DoWhatever);
So... as a summary, I want to have pre-coded (in my library) actions, and the user must choose the actions assigned to a new object when it is instantiated, and those actions don't change.
I guess I could also do it with events, but I don't need to add and remove "actions", they are fixed for the whole life of each object of type B.
So my question is: is there a better, nicer, cleaner solution than this one I've implemented with delegates?
Thank you very much!
So my question is: is there a better, nicer, cleaner solution than this one I've implemented with delegates?
The one improvement I would suggest would be to use the delegates defined in the framework, and not define your own. For example, your Action03 delegate is just a System.Action<int>. This would provide a bit more usability in terms of making the API more discoverable.
That being said, this is effectively using delegates to implement the Strategy pattern. Provided this provides the full functionality you need, it is potentially a good option here, and rather clean.
I think delegates is the only way to go.
Maybe you could also use a decorator pattern if it suits your need ? Its pretty clean, and because its a pattern, its standard, and "easy" to understand as its in some way normalized.
Cant think of any other way, appart maybe from having a heavier use of object composition (and then linking your objects together at runtime, which may be a bit more suple ?

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