0

I have a SQLStatement class which builds up sql query and supports bind parameters (which is stored to the property $params).
I have a PDOAdapter class which acts just like PDO but has additional features such as prepare_query(SQL Statement $sql). It prepares the sql statement and binds the parameter which is stored in $sql->params, then execute it.

And,

I think I want to add a QueryEngine class which can select, insert, update, delete which means it'll build up SQL statement using the SQLStatement class and make PDOAdapter prepare_query it.

I can say its responsibilites are to generate sqlstatement based on the method parameters using SQLStatement class AND make PDOAdapter process it. (Multiple Responsibility)
But, I can also say, its responsibility is to do basic CRUD operations. (Single Responsibility)

Does this QueryEngine class violate Single Responsibility Principle ?
Does this make SQLStatement and PDOAdapter tight-coupled ?
Actually, what is the exact definition of the word Single? I'm confused whether moving a table is single responsibility or multiple responsibility (lift the table up, move it, and put it down).

Terry Djony
  • 1,975
  • 4
  • 23
  • 41
  • Correct me if i'm wrong, but i think the Single Responsability Principle is meant to set a purpose to a class. And later when you'll ask yourself how to expand your code you will know where to put it because you've previously decided which class had which responsability. It's not a matter of class size or what it should do. You can define a class role to be whatever you want, just stick to it once you made a decision (or refactor witch new decisions) – Unex Apr 13 '15 at 08:33
  • @Unex Thanks.. But, you haven't answered my first and second answer. – Terry Djony Apr 13 '15 at 09:42
  • QueryEngine doesn't violate SRP. Maybe SQLstatement and PDOAdapter and tight coupled, but they are a part of the same purpose "make an sqlQuery" which could be one of your module. Then you'd just have to inject this module into your Queryengine and you could work with it without knowing if it's a sql module or file module. Working that way makes sens – Unex Apr 13 '15 at 13:52

1 Answers1

1

Actually, what is the exact definition of the Single-Responsibility?

Imagine for a second, that you build computer's case. It contains things like power-supply, motherboard, HDD inside it. And in any programming language, that could be represented like so:

case = new Case(new Motherboard(), new PowerSupply(), new HDD() ...);

As you can see the parts of the case are completely separated from each other. That means they can be easily replaced without touching another parts. For example, if you need to replace HDD, you'd simply pass another instance of HDD to it. That's it. HDD (and similar parts) has one reason to change.

As for your question, what you want to do needs to be Done in so-called Data Mappers, which abstract a specific table with common abstractions on it.

First of all, I'll show you how it's typically done:

$queryBuilder = new QueryBuilder();
$pdo = new PDO(...)

$dbh = new DBH($pdo, $queryBuilder);

// ... Then somewhere in some mapper

public function fetchById($id)
{
   return $this->dbh->select('*')
             ->from('some table')
             ->where('id', '=', $id)
             ->query();    
}

This adheres to the SRP, because each dependency ($pdo or $queryBuilder) can be replaced easily, therefore they have one reason to change.

As for your original question,

QueryEngine (Correct name is QueryBuilder) will not violtate anything as long as it only knows how to build query strings.

Yang
  • 8,580
  • 8
  • 33
  • 58