[nycphp-talk] OOP noob - general best practices
Paul A Houle
paul at devonianfarm.com
Wed Jan 20 11:34:08 EST 2010
Yitzchak Schaffer wrote:
>
> When should one use a factory method
> $foo = Foo::factory( $this )
> as opposed to using the constructor in the client code
> $foo = new Foo( $this )
There are multiple reasons, but one of the best reasons to write
something like
$foo=Foo::create($arg1,$arg2);
is that Foo:create() can choose a subtype of Foo to instantiate and
return. Based on the arguments, it can return FooA, FooB, FooC or
whatever. This can come in handy.
Another one is that Foo::create() can return false or null rather
than throwing an Exception; that said, much of the time throwing an
Exception is a better error handling mechanism than returning "nothing".
Depending on the language, the chaining of constructors can be
awkward. The issue in PHP is that superclass constructors only get
called if you want to call them, which means that (i) you can do
whatever you like, but (ii) you might forget to to initialize your
superclasses. Java and C# both force you to call the superclass
constructor before you do any substantiative work in the constructor;
it gets awkward if you have to do a lot of work to calculate the
arguments of the superclass constructor.
>
>
> And as corollary, what belongs in a constructor and what doesn't? In
> http://www.slideshare.net/sebastian_bergmann/introduction-to-phpunit-best-practices
>
> slides 19-22, Sebastian Bergmann of PHPUnit alludes to this question,
> but in that presentation is apparently assuming the audience is
> familiar with the answer, and doesn't go into it; his tagline is
> "don't do work in the constructor," but rather do something like the
> following. I don't know what does and does not constitute "work."
>
> $foo = new Foo( $this );
> $foo->build();
>
There are a lot of opinions here, but the general funkiness of
constructors leads a lot of people to this conclusion. In the Scala
language, you've very limited in what you can do in constructors --
constructors really just assign values to variables.
One trouble is components that have a large number of optional
initialization parameters, for instance,
$serversocket=new ServerSocket($portNumber);
$serversocket->AttachCallback($socketCallback);
$serversocket->DenyIP("all");
$serversocket->AcceptIP("192.168.*.*");
$serversocket->bind();
Constructors get awkward when there are a lot of parameters. On the
other hand, there's something nice when you call the constructors and
you ~know~ you've got an object that's completely initialized. using
private or protected constructors and a public "create" method lets you
strike a balance in this department. One way or another you need to be
concious of the lifecycle of your objects.
In many apps there are in-memory objects that correspond to objects
in a persistent store, say an RDBMS and that leads to another set of
conceptual problems. For instance, say we've got a Person object that
represents information about a person... you might call
$person=Person::FetchById(517);
and that would call the constructor and "create" a Person object in RAM
populated with data from the database. Now, there might be another
time you want to create a "Person", so then you might call
$person=Person::Create("paul_houle");
and that actually 'creates' a record in the back end database. Or, on
the other hand, you might do something like
$person=new Person();
$person->Username="paul_houle";
$person->FirstName="Paul";
...
$person->insert();
the tricky thing here is that the word "create" that people toss around
careless actually can mean some very different things. It's important
to keep these apart.
> Based on Amazon reviews, I just bought a copy of the 1994 ed of
> Object-Oriented Software Construction : Bertrand Meyer on Half.com;
> any further recommendations?
>
>
I got a copy of that for a buck a few years ago. It's got some
insight but it's definitely an older book from the C++ and Smalltalk era.
More information about the talk
mailing list