2

SRP states ...

There should never be more than one reason for a class to change.

But why a class? Why not use granularity of a function/method? What instead of separating my functionality into separate classes, I separate it into separate functions?

I don't claim that this works or is advisable in all cases, but in some cases with a few modifications it is fairly similar. When something needs to change I can go to that function and change it. While it may not be applicable to all situations, I often come across situations where I create a new class to single out a responsibility when I can just create a new function inside a class and it will work just as well.

Example -- Before Separation

class ProductDataMapper
{
    function findById($id)
    {
        // data retrieval concern i.e. read info from DB
        $data = array('name' => 'Mike');

        // data-to-object mapping concern
        $productParams = array();
        $productParams['name'] = $data['name_column'];

        $product = new Product($productParams);

        return $product;
    }
}

Example -- After Separation

class ProductDataMapper
{
    function findById($id)
    {
        $data = $this->dataConcern($id);
        $productParams = $this->mappingConcern($data);
        $product = new Product($productParams);
        return $product;
    }

    function dataConcern($id)
    {
        $data = $db->get("SELECT...$id");
        return $data;
    }

    function mappingConcern($data)
    {            
        $productParams = array();
        $productParams['name'] = $data['name_column'];
        return $productParams;
    }
}

So if My SQL table changes but data remains the same, I only need to change one method ::dataConcern(). If my binding changes between the schema and object parameters, all I need to change is ::mappingConcern().

Why create a whole other classes to handle those responsibilities?

Dennis
  • 8,157
  • 5
  • 36
  • 68

1 Answers1

3

Why create a whole other classes to handle those responsibilities?

Because when you're doing Object Oriented Programming, your focus should be on the objects. They are your unit of work for making the design and providing abstraction. And most importantly, they are your unit of reuse. By letting them change for different reasons, you're forcing people who are using them for one reason be impacted by a change made to another reason that they don't care about.

I am on record as saying that SRP works just as well through the lens of functional/imperative programming. The difference is that in those paradigms, your unit of reuse isn't a class, but a function or module.

Telastyn
  • 108,850
  • 29
  • 239
  • 365
  • so really it is an *ideology* reason, because class is considered to be the smallest working element in OO. It still does not stop me from mixing related concerns (related to `DataMapper`) inside one class using in-class functions, thereby mixing paradigms. For example, in context of this question I can leave functions `dataConcern()` and `mappingConcern()` as is, or I can create new classes to house them and inject those classes into `DataMapper` – Dennis Jul 02 '15 at 14:42
  • @dennis - I wouldn't say it's _just_ ideology. It's how much pain you cause consumers (including yourself) due to change. – Telastyn Jul 02 '15 at 15:06