never_had_a_name
never_had_a_name

Reputation: 93166

benefit of having a factory for object creation?

I'm trying to understand the factory design pattern.

I don't understand why it's good to have a middleman between the client and the product (object that the client wants).

example with no factory:

$mac = new Mac();

example with a factory:

$appleStore = new AppleStore();
$mac = $appleStore->getProduct('mac');

How does the factory pattern decouple the client from the product?

Could someone give an example of a future code change that will impact on example 1 negative, but positive in example 2 so I understand the importance of decoupling?

Thanks.

Upvotes: 6

Views: 314

Answers (3)

Bill Karwin
Bill Karwin

Reputation: 562270

This example returns an object of type Mac and it can never be anything different:

$mac = new Mac();

It can't be a subclass of Mac, not can it be a class that matches the interface of Mac.

Whereas the following example may return an object of type Mac or whatever other type the factory decides is appropriate.

$appleStore = new AppleStore();
$mac = $appleStore->getProduct('mac');

You might want a set of subclasses of Mac, each representing a different model of Mac. Then you write code in the factory to decide which of these subclasses to use. You can't do that with the new operator.

So a factory gives you more flexibility in object creation. Flexibility often goes hand in hand with decoupling.


Re your comment: I wouldn't say never use new. In fact, I do use new for the majority of simple object creation. But it has nothing to do with who is writing the client code. The factory pattern is for when you want an architecture that can choose the class to instantiate dynamically.

In your Apple Store example, you would probably want some simple code to instantiate a product and add it to a shopping cart. If you use new and you have different object types for each different product type, you'd have to write a huge case statement so you could make a new object of the appropriate type. Every time you add a product type, you'd have to update that case statement. And you might have several of these case statements in other parts of your application.

By using a factory, you would only have one place to update, that knows how to take a parameter and instantiate the right type of object. All places in your app would implicitly gain support for the new type, with no code changes needed. This is a win whether you're the sole developer or if you're on a team.

But again, you don't need a factory if you don't need to support a variety of subtypes. Just continue to use new in simple cases.

Upvotes: 1

Joey Adams
Joey Adams

Reputation: 43380

I think it has to do with the resources needed to construct some types of objects.

Informally, if you told someone to build a Mac, it would be a painstaking process that would take years of design, development, manufacturing, and testing, and it might not be done right. This process would have to be repeated for every single Mac. However, if you introduce a factory, all the hard work can be done just once, then Macs can be produced more cheaply.

Now consider Joomla's factory.php. From what I can tell, the main purpose of JFactory is to pool objects and make sure objects that should be the same aren't copied. For instance, JFactory::getUser() will return a reference to one and only one object. If something gets changed in that user object, it will appear everywhere. Also, note that JFactory::getUser() returns a reference, not a new object. That is something you simply cannot do with a constructor.

Often, you need local context when constructing an object, and that context may persist and possibly take on many forms. For instance, there might be a MySQL database holding users. If User objects are created with a constructor, you'll need to pass a Database object to the constructor (or have it rely on a global variable). If you decide to switch your application to PostgreSQL, the semantics of the Database object may change, causing all uses of the constructor to need review. Global variables let us hide those details, and so do factories. Thus, a User factory would decouple the details of constructing User objects from places where User objects are needed.

When are factories helpful? When constructing an object involves background details. When are constructors better? When global variables suffice.

Upvotes: 5

SeanJA
SeanJA

Reputation: 10354

Don't know if I can put it any better than IBM did https://www.ibm.com/developerworks/library/os-php-designptrns/#N10076

Upvotes: 2

Related Questions