Реализация принципа единой ответственности

У меня есть класс SQLStatement, который создает запрос sql и поддерживает параметры привязки (которые хранятся в свойстве $ params).
У меня есть класс PDOAdapter, который действует просто как PDO, но имеет дополнительные функции, такие как prepare_query(SQL Statement $sql). Он подготавливает оператор sql и связывает параметр, который хранится в $sql->params, а затем выполняет его.

И,

я думаю, что хочу добавить класс QueryEngine, который может выбирать, вставлять, обновлять, удалять, что означает, что он будет создавать оператор SQL с помощью SQLStatement и заставьте PDOAdapter подготовить_запрос.

Я могу сказать, что в его обязанности входит создание sqlstatement на основе параметров метода с использованием класса SQLStatement И make PDOAdapter обработайте его. (Множественная ответственность)
Но я также могу сказать, что он отвечает за выполнение основных операций CRUD. (Единая ответственность)

Нарушает ли этот класс QueryEngine принцип единой ответственности?
Делает ли это SQLStatement и PDOAdapter тесной связью?
На самом деле, что такое точное определение слова Single? Я не понимаю, является ли перемещение стола одной или несколькими обязанностями (поднимите стол, переместите и положите).


person Terry Djony    schedule 13.04.2015    source источник
comment
Поправьте меня, если я ошибаюсь, но я думаю, что принцип единой ответственности предназначен для того, чтобы установить цель для класса. А позже, когда вы спросите себя, как расширить свой код, вы будете знать, где его разместить, потому что вы заранее решили, какой класс имеет какую ответственность. Дело не в размере класса или в том, что он должен делать. Вы можете определить роль класса как угодно, просто придерживайтесь ее, как только вы примете решение (или проведите рефакторинг с новыми решениями)   -  person Unex    schedule 13.04.2015
comment
@Unex Спасибо .. Но вы не ответили на мой первый и второй ответ.   -  person Terry Djony    schedule 13.04.2015
comment
QueryEngine не нарушает SRP. Возможно, SQLstatement и PDOAdapter и тесно связаны, но они являются частью той же цели, что и sqlQuery, который может быть одним из ваших модулей. Тогда вам просто нужно будет вставить этот модуль в свой Queryengine, и вы сможете работать с ним, не зная, является ли это модулем sql или файловым модулем. Работа таким образом делает разумным   -  person Unex    schedule 13.04.2015


Ответы (1)


Собственно, каково точное определение единоличной ответственности?

Представьте на секунду, что вы собираете компьютерный корпус. Внутри него находятся блок питания, материнская плата, жесткий диск. И на любом языке программирования это можно представить так:

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

Как видите, части корпуса полностью отделены друг от друга. Это означает, что их можно легко заменить, не касаясь других деталей. Например, если вам нужно заменить жесткий диск, вы просто передадите ему другой экземпляр жесткого диска. Вот и все. HDD (и аналогичные детали) имеет одну причину для замены.

Что касается вашего вопроса, то, что вы хотите сделать, должно быть выполнено в так называемых Data Mappers, которые абстрагируют конкретную таблицу с общими абстракциями на ней.

Прежде всего, я покажу вам, как это обычно делается:

$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();    
}

Это соответствует SRP, потому что каждую зависимость ($pdo или $queryBuilder) можно легко заменить, поэтому у них есть одна причина для изменения.

Что касается вашего исходного вопроса,

QueryEngine (Правильное имя - QueryBuilder) ничего не нарушит, если только знает, как строить строки запроса.

person Yang    schedule 16.04.2015