php - Instantiation of new object or reusing the same one for storing data

684

I have the following PHP class calledCustomer with functioncreate() which stores customer's data into database:

class Customer
{
  public $createdby;
  public $cname;

  public function create()
  {
    ...
  }
}

Since I need to store more customers in a loop where only name ($cname variable) changes (for the sake of simplicity here the$createdby variable is the same for all created customers within this loop - because the same user created allCustomers), the question rises - what is (and why) the better practice;

method A) reusing the same Customer object where one changes only properties which are changed:

$Customer=new Customer();
$Customer->createdby='somebody';
foreach($cnames as $cname)
{
  $Customer->cname=$cname;
  $Customer->create();
}

method B) instatiating new Customer object and setting all properties for each particular creation like:

foreach($cnames as $cname)
{
  $Customer=new Customer();
  $Customer->createdby='somebody';
  $Customer->cname=$cname;
  $Customer->create();
}

If I'd like to make an array of Customer objects, for sure, I would have to use second method. But here's not that case. I don't see any drawback of first principle with reusing the existing object for storing more customers into database but maybe I'm wrong. So I ask just in case what is better practice and why!

777

Answer

Solution:

Static instantiators

First of - if the method is intended to be instantiation method, logically is must mestatic (because there is no object context before instantiation). The case of instantiation methods is one of legal use-cases for static methods. Thus, your regularcreate() method is wrong, since it's operating on object context. You may instead use class magic method for that, of course - in case if you're certain that instantiation logic will always be same.

Using a factory

Another way is to use some factory class to instantiate your object with given data - therefore, implement Factory pattern. In your case that may be like:

class CustomerFactory
{
    public function createByNames($name, $createdBy)
    {
        $customer = new Customer();
        $customer->setName($name);
        $customer->setCreatedBy($createdBy);
        return $customer;
    }
}

The benefit here is - that your original class may get rid of instantiation logic and the factory will be responsible for creating valid entity in terms of business-rules & integrity. You may, for example, add some validation to your instantiation and pass certain validator as a dependency:

class CustomerFactory
{
    public function createByRawData(CustomerValidator $validator, array $customerData)
    {
        if(!$validator->check($customerData))
        {
            //or use some namespace, which I omit here to simplify case:
            throw new CustomerInstantiationException('Creation error '.$validator->getErrorMessage());
        }
        $customer = new Customer();
        $customer->setData($customerData);
        return $customer;
    }
}

As you can see, this approach if much more flexible and scalable - and won't require modification ofCustomer class - since the logic now belongs to factory.

Collection instantiation

In simple case you can use a factory to instantiate multiple objects. You may either return an array of such objects or add special collection-like entity (which will behave like collection, so, most probably, extend such interfaces as Iterator). The choice is yours - but I recommend second one - and, again, because you'll be able to extend your logic without changing factory code (only your collection behavior, which can be later extended with some things).

So, answer to your question about re-using would be - you need to decide, if different instances are needed. If they are, and the intention is to interact with multiple instances - then you should create them separately. And, if they are intended to behave like some sort of collection - then good idea would be to create custom collection class (which will implement Iterator or some custom collection interface) - or, at least, use an array of such objects. If the collection is needed, then I suggest to put instantiation logic to separate factory, like I've described above.

When you are re-using same object, you' obviously, have only one entity, which is changing it's state. If that is a proper reflection of your logic (that is: you really have only one customer), then you may use it. But if your customers are logically different entities, then it's wrong approach, since you wont be able to operate on them after you'll re-write same object.

Objects are your business-entities reflection, their behavior are business-logic reflection

812

Answer

Solution:

Seems that both methods are equal, but I would prefer second one. It will take me apart of some potential troubles, connected with any internal details ofcreate() method (for example it may generate some unique hash in somebeforeCreate() method ifCustomerobject does not contain it).

People are also looking for solutions to the problem: Make ODBC Connection in PHP Script from Hosted Platform

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.