views:

432

answers:

9

My understanding of a factory is that it encapsulates instantiation of concrete classes that all inherit a common abstract class or interface. This allows the client to be decoupled from the process of determining which concrete class to create, which in turn means you can add or remove concrete classes from your program without having to change the client's code. You might have to change the factory, but the factory is "purpose built" and really only has one reason to change--a concrete class has been added/removed.

I have built some classes that do in fact encapsulate object instantiation but for a different reason: the objects are hard to instantiate. For the moment, I'm calling these classes "factories", but I'm concerned that might be a misnomer and would confuse other programmers who might look at my code. My "factory" classes don't decide which concrete class to instantiate, they guarantee that a series of objects will be instantiated in the correct order and that the right classes will be passed into the right constructors when I call new().

For example, for an MVVM project I'm working on, I wrote a class to ensure that my SetupView gets instantiated properly. It looks something like this:

public class SetupViewFactory
{
    public SetupView CreateView(DatabaseModel databaseModel, SettingsModel settingsModel, ViewUtilities viewUtilities)
    {
        var setupViewModel = new SetupViewModel(databaseModel, settingsModel, viewUtilities);
        var setupView = new SetupView();
        setupView.DataContext = setupViewModel;
        return setupView;
    }
}

Is it confusing to call this a "factory"? It doesn't decide among several possible concrete classes, and its return type is not an interface or abstract type, but it does encapsulate object instantiation.

If it's not a "factory", what is it?


Edit

A number of people have suggested that this is actually the Builder Pattern.

The definition of the Builder Pattern from dofactory is as follows:

Separate the construction of a complex object from its representation so that the same construction process can create different representations.

This seems like a little bit of a stretch also. The thing that bothers me is the "different representations". My purpose is not to abstract the process of building a View (not that that isn't a worthy goal). I'm simply trying to put the logic for creating a specific view in one place, so that if any of the ingredients or the process for creating that view change, I only have to change this one class. The builder pattern really seems to be saying, "Let's create a general process for making Views, then you can follow that same basic process for any View you create." Nice, but that's just not what I'm doing here.


Edit 2

I just found an interesting example in a Wikipedia article on Dependency Injection.

Under "Manually Injected Dependency", it contains the following class:

public class CarFactory {

    public static Car buildCar() {
        return new Car(new SimpleEngine());
    }

}

This is almost exactly the usage I have (and, no, I did not write the wiki article :)).

Interestingly, this is the comment following this code:

In the code above, the factory takes responsibility for assembling the car, and injects the engine into the car. This frees the car from knowing about how to create an engine, though now the CarFactory has to know about the engine's construction. One could create an EngineFactory, but that merely creates dependencies among factories. So the problem remains, but has at least been shifted into factories, or builder objects. [my emphasis]

So, this tells me that at least I'm not the only one who's thought of creating a class to help with injecting stuff into another class, and I'm not the only one who attempted to name this class a factory.

+1  A: 

GoF call it "Builder"

Victor Sergienko
As far as I know, a Builder needs a Director and Product
Erkan Haspulat
Director is the client code, and Product is evidently a SetupView.
Victor Sergienko
+1  A: 

I think, it is a "Factory". When I look at the class declaration, I feel happy to see that this is a "Factory", and what's more, it is a "Factory" of SetupView objects. So I know that this Factory will give me concrete and correctly built SetupView instances.

Erkan Haspulat
+4  A: 

It looks to me like what you have there is more of a Builder pattern than a Factory pattern.

Joseph
A: 

You could call it a "Wizard".

T.E.D.
+1  A: 

A "Factory" is anything that encapsulates the instantiation of new objects. Why, or what the objects are, doesn't matter. The most common use is as you describe, but other purposes that do not fit that description can also be called a Factory. The fundamental idea, (which I don't think any but the most anal or picky developer would misconstrue), is that the thing instantiates new objects for you...

Charles Bretana
+1  A: 

This seems a little weird to me. It's not an abstract factory but it doesn't quite fit the Builder pattern either. What would make the most sense to me is instead of having the SetupViewFactory with the method CreateView, I would move this method to the SetupView class and make it static. So you'd have...

public class SetupView
{
    public static SetupView CreateView(DatabaseModel databaseModel, SettingsModel settingsModel, ViewUtilities viewUtilities)
    {
        var setupViewModel = new SetupViewModel(databaseModel, settingsModel, viewUtilities);
        var setupView = new SetupView();
        setupView.DataContext = setupViewModel;
        return setupView;
    }
}

Now you have what is called the static factory or a factory method. You can take it one step further and privatize the SetupView constructors so that the only way to get an instance of SetupView is to call the factory method.

In response to OP's Comment:

If there is such a need for separation I would avoid creating the SetupViewModel anywhere in this part of the code. Instead just pass in the SetupViewModel you want to associate with your SetupView instead of the constituent properties to pass to SetupViewModel's constructor. So the code becomes...

public class SetupView
{
    public static SetupView CreateView(SetupViewModel model)
    {
        var setupView = new SetupView(); { DataContext = model };
        return setupView;
    }
}
Jason Punyon
@Jason that would definitely bring it over into the factory side. You could conversely split up the CreateView into separate functionality and have the final step return the SetupView, which would lean toward Builder. I think it could definitely go both ways.
Joseph
Interesting idea, but with my current design, there is I think a desirable separation between the SetupView and SetupViewModel. I might wish to use a different ViewModel with my View, which would mean I could just create another factory (or edit the factory) rather than messing with my View.
DanM
@Jason, thanks for the addition to your answer, but now we are back to square one :) The whole point of what I'm trying to do is automate and ensure the process of creating a ViewModel, creating a View, setting the DataContext, and returning a view that is "ready to go". What you've done here is move part of this responsibility into the SetupView class, which is okay (maybe even good), but now, whatever class is responsible for calling `SetupView.CreateView()` still needs a name. (And note, I have other examples that are more complicated than this one.)
DanM
@DanThMan...ugh. What a maroon. Of course that's the opposite direction from what you want. I'm a doofus sometimes...
Jason Punyon
A: 

I would tend agree with Jason above. To me it is more like a Builder pattern but if you turned SetupView into an interface it would be more like a Factory pattern. The key to the Factory pattern is letting the Factory pattern do all the work in deciding what to return from the function call. So I would think that you would have to have a switch selecting between various options given the input parameters.

Excalibur2000
+4  A: 

This doesn't sound much different to me than a constructor for an instance of SetupView. Perhaps too much code context has been elided from your example, but I don't see why what you have right there couldn't simply be written as a constructor, and the arguments passed as args to the constructor.

Judging strictly from GoF patterns, I think it misses the mark on Factory for two reasons:

  1. there is no family of related/dependent objects
  2. the concrete class is, indeed, specified

With regard to Builder, I think it misses in the aspect of variance of products.

When I teach Design Patterns courses, I tell students to look not just at the intent of a pattern when trying to determine "best fit", but rather look at applicability and structure/participants. The intent can help you rule things out, but applicability & structure/participants are what will help you home in.

If you can identify what part of your design fulfills the various roles of the participants in either (Abstract) Factory or Builder, then you've made a good case for using that nomenclature.

Chris Cleeland
Thanks, @Chris, I agree with you. My class doesn't really follow either pattern, but to be honest, it wasn't really intended to. What I do want to know is whether hijacking a common class naming scheme from a pattern is a bad thing if I'm not really implementing that pattern. Any thoughts on that? And also, please see my second edit to my question.
DanM
@Chris, also, please see my comment on @Jeff Sternal's answer for an explanation on why I don't just write a constructor for SetupView.
DanM
To the extent that one of primary purposes of patterns in general is to define a common language, then, yes, I think it's misleading to call it something that it's not, *especially* if you are using other elements of the pattern language in a more "true" way. For example, we can use the word "car" in conversation and never have to specify the number of wheels, the existence of an engine, doors, size, etc. because that term embodies a common understanding. For me to call something a "car" in our conversation, when it's really a semi-trailer is misleading.
Chris Cleeland
Also, I read thru your explanation as to why you don't use two simple ctors. Originally I was thinking along the lines of two simple ctors, and a "convenience" ctor for SetupView that took the same set of arguments as SetupViewModel's ctor and did all the grunt work behind the scenes.However, I understand the need to keep things separated in your situation. I'm still not sure you have either a GoF factory or builder despite the parallels in the wikipedia article, but that may not matter. (cont'd)
Chris Cleeland
Ultimately, what I think *is* important is that if one must spend a lot of time explaining how what you something is a Factory or a Builder or a Constructor or a <insert some pattern name here>, then it may simply be too far of a stretch. Call it Factory-like, or just explain what it does. A central idea behind patterns is to reduce the amount of explicit communication that has to occur, so if you have to do that anyway, you've possibly muddled the issue worse than not having used a name at all.
Chris Cleeland
Thanks very much, Chris.
DanM
+1  A: 

Why not two classes with simple constructors?

 public class SetupViewModel {
      public SetupViewModel(DatabaseModel databaseModel, SettingsModel settingsModel, ViewUtilities viewUtilities) {
          this.DatabaseModel = databaseModel;
          this.SettingsModel = settingsModel;
          this.ViewUtilities = viewUtilities;
      }
 }

and

 public class SetupView {         
      public SetupView(SetupViewModel model) {              
          this.DataContext = model;
      }
 }

This way, both classes plainly state what they need to be constructed.

Jeff Sternal
Thanks, Jeff. That's almost exactly what I have already for `SetupViewModel`. I don't have the `SetupView` set it's own DataContext mostly because that is not the convention used for the MVVM pattern. The idea is that the `View` is supposed to be generated by designers/artists using, e.g., Expression Blend, so it's best to have has little code in the code-behind as possible. Also, you can plug in a new view anytime you want without having to add the code that sets the DataContext.
DanM
Ah, got it! In that case this seems entirely appropriate - though I agree with others that this is awfully close to being a builder. If you add a virtual CreateSetupView method (called in lieu of the new statement), you're there - and that might be useful.
Jeff Sternal