Re: When to instantiate a new class

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



What Larry said, basically.

You create a new instance of a class when you need a new instance of a
class. In your particular example, "databaseInterface" would presumably
wrap a database connection (which in turn has information about the current
transaction/savepoints, DB variables...), maybe some information about the
schema, maybe a cache of some kind or an identity map, etc. You would just
instantiate that once near the start of the request and hold onto it until
you don't need it anymore/until the end, to let it be garbage collected.
Even if you're not using transactions or any fancy stuff and your
databaseInterface class is effectively stateless, you should keep the door
open to implement fancy stuff later by holding onto the same instance
throughout the request. Not to mention, you don't want to incur the
overhead of connecting to the database in every method.

That leaves having a class property vs passing it into each method. It
depends on the purpose of the "screen" class. If the purpose of the class
is such that it is *always *going to need a "databaseInterface" (I guess it
is), then instantiate it in the constructor (or take one as a constructor
parameter) and set it as a property. Otherwise, pass it through the methods
that need it as a parameter.

You don't *have *to access the property through a getter. You can if you
want. It doesn't buy you much besides maybe making it a bit easier to
re-implment by delegating to a "databaseInterface" from somewhere else.

Also, Google "singleton bad" on why you generally shouldn't use global
state (singletons), and should instead pass dependencies explicitly using
properties/parameters.

Also also, I've never quite figured out why "dependency injection
containers" exist. Dependency injection just means you pass through to a
class/method the things it needs, rather than letting it instantiate them
itself, so the caller can decide how those dependencies are implemented. If
lots of things need the same set of dependencies, then just wrap them all
up in another class that has properties or getters for each. It's not hard.

Cheers


On Sat, Jun 20, 2015 at 8:15 AM, Larry Garfield <larry@xxxxxxxxxxxxxxxx>
wrote:

> On 6/17/15 3:56 PM, Ramiro Barrantes wrote:
>
>> Hello,
>>
>> This is a very basic question, i just don't know php well enough to know
>> what's best.  I have a screen class and a database class.  The screen class
>> handles everything related to what goes on the screen, but its many
>> functions often need to use the database class to get relevant
>> information.  The question I have is:
>>
>> How often should I instantiate the database class? Should I do it once
>> with say, the constructor of the screen class? Or with the specific method,
>> or pass it as a variable?
>>
>> For example:
>>
>> INSTANTIATING WITHIN EACH FUNCTION
>> function method($variable) {
>>     $db = new databaseInterface():
>>     ...
>> }
>>
>> or
>>
>> PASSING IT AS A VARIABLE FOR EACH FUNCTION
>> function method($variable,$db) {
>>     ...
>> }
>>
>> or
>>
>> CREATING IT AS PART OF THE SCREEN CONSTRUCTOR AND ACCESSING IT WITH A
>> "getter"
>> class screen {
>>    private $db;
>>    function construct() {
>>       $db=new databaseInterface();
>>    }
>>
>>    function getDatabaseInstance() {
>>      return($db);
>>   }
>> }
>>
>> Thanks in advance,
>> Ramiro
>>
>
> 1) The classes you're talking about (the DB connection and the output
> channel) are called "Services". That is, they're classes that do not
> contain data per se, only logic. Services should, generally, only have a
> single instance in your entire application. You may have different
> instances of the same class with different constructor parameters if they
> are for different purposes; eg, two different DB connections for two
> different databases. But those are separate services at that point.
>
> 2) Enforcing that there's only a single instance of each service is *not
> the service's job*. That is, *do not make them singletons*. Ever. Singleton
> is an anti-pattern that makes testing harder and your code less flexible.
>
> 3) The way to wire the objects together is called Dependency Injection,
> which is really just the fancy-pants way of saying "pass in what you need".
> In your example:
>
> class Connection {
> // ...
> }
>
> class Screen {
> protected $conn;
>
> public function __construct(Connection $conn) {
> $this->conn = $conn;
> }
>
> public function doStuff() {
> $result = $this->conn->query(...);
> // ...
> }
> }
>
> $conn = new Connection(...);
>
> $screen = new Screen($conn);
>
>
> 4) Your output channel should, in fact, NOT be talking directly to the
> database in most cases. There should be an intermediary that coordinates
> that. If it's per-URL, then it's generally called a Controller and should
> be very very simple. For example:
>
> class Controller {
>
> protected $conn;
> protected $screen;
>
> public function __construct(Connection $conn, Screen $screen) {
> $this->conn = $conn;
> $this->screen = $screen;
> }
>
> // Something routes the request to this method; exactly how is
> // out of scope at the moment.
> public function showUser($userId) {
> $result = This->conn->query("SELECT name FROM users WHERE id=:id", [':id'
> => $user_id];
> $name = $result->fetchOne();
>
> $screen->showName($name);
> }
>
> Note that taking a dependency injection approach (which you should) does
> lead quickly to a lot of "wiring" code on your part to inject everything.
> The answer to that is the scarily-named "dependency injection container".
> There are many that already exist for PHP. The simplest/easiest to get
> started with is Pimple:
>
> http://pimple.sensiolabs.org/
>
>
>
> --Larry Garfield
>
>
> --
> PHP General Mailing List (http://www.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>

[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux