Способен ли объект сохранить себя в базе данных, портит ли сплоченность класса?
Говоря с точки зрения объектно-ориентированного проектирования, думаете ли вы, что предоставление возможности сохранения себя в базе данных для объекта портит единство класса?
Представить:
Product p = new Product()
{
Name = "Joy Rider",
Price = 100,
Currency = "USD"
};
Как вы думаете, сохранить этот продукт p в базе данных лучше сделать следующим образом:
p.Save();
или в некотором роде что-то вроде этого:
ProductServices.SaveProduct(p);
Как вы думаете?
3 ответа
Это мешает принципу единой ответственности. Цель класса Product в вашем примере - представить Product и операции над этим продуктом. Взаимодействие с базой данных не является основной частью ответственности класса.
Наличие класса ProductServices повышает удобство сопровождения вашего кода. Предположим, что логика сохранения объектов в базе данных должна была измениться (что это возможно). Вы хотите изменить каждый класс сущностей в вашей системе?
Объект, который может сохранить себя в базе данных, будет нарушать SRP (принцип единой ответственности).
Упорство само по себе является ответственностью и должно решаться специальными классами.
Это было бы в дополнение к низкой сплоченности - члены, которые имеют отношение к постоянству, не имеют отношения к тем, которые не имеют и не будут использоваться в тех методах класса, которые не имеют дело с постоянством.
Что касается только объектно-ориентированного проектирования, то нет ничего плохого в том, что метод Save является частью Product. Это на самом деле предпочтительный метод в мире объектно-ориентированного дизайна. И с точки зрения чистой ОО вы бы не хотели, чтобы он был разбит на части, потому что это более функционально, чем объект.
Однако, если вы верите в Принцип инверсии зависимости, который гласит, что модули высокого уровня не должны зависеть от модулей низкого уровня; тогда был бы уместен метод Save, но он должен принимать абстрактный тип соединения в качестве параметра. Это даст вам хорошую объектную модель, которая включает в себя метод Save, но не будет знать тип соединения.