0

(Forgive me if this is not clear; I'm not quite sure what I'm asking.)

Why does the Kohana ORM module use a factory method to create instances of ORM classes, given that one must always pass factory() the name of the class that one wants to get back?

My understanding of the factory pattern is that it is used when the client code doesn't know beforehand the (concrete) type of the object that will result.

The Kohana guide does say that the following are both acceptable:

$user = ORM::factory('User');
// Or
$user = new Model_User();

But why use the first over the second?

Sam Wilson
  • 4,402
  • 4
  • 29
  • 30

3 Answers3

1

@AmazonDreams raised a good point. "User" is a logical entity in that application, but the class name may not be named this way. ORM factory method provides abstraction for instantiating models.

You might have noticed, factory method is used throughout the framework. E.g. Validation::factory, Response::factory, View::factory. It is almost a convention to use Factory pattern to provide abstraction for instantiation.

Community
  • 1
  • 1
hongster
  • 544
  • 3
  • 12
1

The correct answer is simply 'chaining'.

In PHP 5.4 you can now do (new Model_User)->save(), but in the past you would have to do this as two separate lines of code. So Model::factory('User')->save() wins. However this is no longer necessary.

Notice I didn't mention ORM. Kohana uses this pattern quite a bit. But in some cases, like ORM, the factory method actually takes additional arguments which are sent to the constructor.

By the way, there is a difference between a factory method and the factory pattern. Don't confuse them.

Paul Schwarz
  • 1,828
  • 1
  • 15
  • 24
  • Ah, thank you, good point. So, would you say that ORM::factory() isn't really a factory *pattern* (but is of course a factory method)? – Sam Wilson Aug 19 '13 at 04:26
  • That is correct. It is a factory method. The two concepts are related, but there is a difference which is well explained here http://stackoverflow.com/a/5740020/2694806 – Paul Schwarz Aug 19 '13 at 08:18
0

Why don't you run some tests?

// Will throw an error
$users = new Model_User()->find_all();

// Correct
$users = new Model_User();
$users = $users->find_all();

// Won't throw an error and does what you want in one line
$users = ORM::factory('User')->find_all();

If you look at the code of the factory you can see that it does not really do anything special.

public static function factory($model, $id = NULL)
{
    // Set class name
    $model = 'Model_'.$model;

    return new $model($id);
}

Which really comes in handy in things like these (silly example as Kohana got a build in auth system)

if(ORM::factory('User', $id)->is_enabled())
{
    // Allow login
}

In short:

  1. It allows you to chain methods you build
  2. It saves you the pain of having to write Model_ every time; I personally prefer writing ORM::factory()
  3. It is instantly clear to others that the object you instantiate is an ORM object (while it does allow you to instantiate non-ORM models through that factory, but we have the Model::factory() for that)
AmazingDreams
  • 3,136
  • 2
  • 22
  • 32
  • You're quite right about all that (and I agree at the ease of use) but I guess I was really getting at the usage of the factory *pattern* — we never call ORM::factory('Thing') expecting to get anything other than a Model_Thing back. – Sam Wilson Aug 15 '13 at 05:37
  • The factory is there to put `Model_` before `Thing`. [Strictly speaking it is a correct use of the factory pattern](http://stackoverflow.com/questions/2083424/what-is-a-factory-design-pattern-in-php) . Besides the factory allows you to be flexible about your classes, which, of course, is taken away by the fact that they state that it does not matter whether you use the factory or not; trouble when wishing to upgrade to a new version of Kohana if they changed the way the ORM models are instantiated (see no reason why they would). Bottom line; use the factory :) – AmazingDreams Aug 15 '13 at 08:11