I've been reading up about SOLID design principles, currently looking at the 'Single Responsibilty Principle', but I was curious on the use case for this principle. At the company I work at, we have DAOs which have methods of read, insert & update to manage a record in the database.
Would something like this break the 'Single Responsibilty Principle'? If so, would you then need classes for each inserting, reading & updating?
Example DAO:
class UserDAO {
public function read(where: object) {
// read code
}
public function insert(user: User) {
// insert code
}
public function update(user: User) {
// update code
}
}
Single Responsibility Principle states that
A class must have only one reason to change.
Let's say we have UserDAO with methods read, save, delete, update. So, this class will only be changed when there will be changes related to User. So, it has a single reason for a change i.e User.
So, I think it doesn't violate SRP (Single Responsibility Principle) if implemented correctly.
void save(User user){
//user related logic
}
void save(User user){
// user related logic and address logic encapsulated inside address class
//eg: address.getAddress(user.getId);
}
In the above case, it doesn't violate SRP because the save method will only be changed when there is a change in User logic. The address logic is handled by Address class per se.
For eg: if save method looks like:
void save(User user){
Address address = new Address();
//Address logic
Payment payment = new Payment();
//Payment logic
}
In the above code, any changes in Address or Payment logic will make this DAO save method change as well. It violates SRP.
So, it really depends on the implementation.
Related
Let's consider the following example:
class User
{
}
class FirstUseNotification
{
function show(User user)
{
// check if it was already shown, return if so
// show a notification
// mark it as shown in the db or whatever
}
}
class SomeController
{
function someMethod()
{
firstUseNotification->show(user);
}
}
The show() method seems to break single responsibility by doing 3 things. So i figure this could be rewritten as such:
class User
{
}
class FirstUseNotification
{
function show(User user)
{
// show a notification
}
function shouldShow(User user)
{
// return true if not yet shown
}
function markAsShown(User user)
{
// flag notification as shown
}
}
class SomeController
{
function someMethod()
{
if (firstUseNotification->shouldShow(user))
{
firstUseNotification->show(user);
firstUseNotification->markAsShown(user);
}
}
}
So here's what i'm interested in:
Am i correct to assume that in second example the notification class is now OK with single responsibility principle?
All of the things that were happening in show() method are gone, but ... they are simply relocated to a method in a controller, so shouldn't it mean that this controller method now breaks single responsibility? If so, how can this be done to comply?
The single responsibility principle (SRP) is often stated in the form of a quote by Robert C. Martin:
A class should have only one reason to change.
In this case, the purpose of your FirstUseNotification class is to show a notification to a first-time user. So the only reason this class should need to change is if this purpose changes; and that is one reason, so the SRP is satisfied.
Note that this definition applies to a class, not to a method. That said, splitting this method into three methods probably violates the SRP, because if a user of this class needs to call three methods instead of one, then that user class has the responsibility of checking whether to show the notification, and marking the user as shown, in addition to the user class's own responsibility. FirstUseNotification's responsibility is to "show a notification to a first-time user", not to provide an API that allows other classes to do that when it is not their responsibility.
In practice the FirstUserNotification class might have other reasons to change, if the details of how it shows the notification or accesses the database change. This can ideally be prevented by having stable interfaces for the notification and database classes, so that changes to those classes don't require changes to FirstUseNotification or other classes which show notifications and/or access the database. In practice this is not always 100% achieved, in which case the FirstUseNotification class might have some responsibilities to do with the details of showing a notification or accessing the database. But in theory, if those other classes handle their own responsibilities properly, then this class has only one reason to change.
Let's say I have a class Order. An Order can be finished by calling Order.finish() method. Internally, when an Order is finished, a finishing date is set:
Order.java
public void finish() {
finishingDate = new Date();
}
In the application's business logic, there is no need to expose an Order's finishingDate, so it is a private field without a getter.
Imagine that after finishing an Order, I want to update it in a database. For instance, I could have a DAO with an update method:
OrderDao.java
public void update(Order order) {
//UPDATE FROM ORDERS SET ...
}
In that method, I need the internal state of the Order, in order to update the table fields. But I said before that there is no need in my business logic to expose Order's finishingDate field.
If I add a Order.getFinishingDate() method:
I'm changing the contract of Order class without adding business value, ubt for "technical" reasons (an UPDATE in a database)
I'm violating the principle of encapsulation of object oriented programming, since I'm exposing internal state.
How do you solve this? Do you consider adding getters (like "entity" classes in ORM do) is acceptable?
I have seen a different approach where class itself (implementation) knows even how to persist itself. Something like this (very naive example, it's just for the question):
public interface Order {
void finish();
boolean isFinished();
}
public class DbOrder implements Order {
private final int id;
private final Database db;
//ctor. An implementation of Database is injected
#Override
public void finish() {
db.update("ORDERS", "FINISHING_DATE", new Date(), "ID=" + id);
}
#Override
public boolean isFinished() {
Date finishingDate = db.select("ORDERS", "FINISHING_DATE", "ID=" + id);
return finishingDate != null;
}
}
public interface Database {
void update(String table, String columnName, Object newValue, String whereClause);
void select(String table, String columnName, String whereClause);
}
Apart from the performance issues (actually, it can be cached or something), I like this approach but it forces us to mock many things when testing, since all the logic is not "in-memory". I mean, the required data to "execute" the logic under test is not just a field in memory, but it's provided by an external component: in this case, the Database.
This is an excellent observation in my opinion. No, I don't consider adding any methods just for technical reasons acceptable, especially getters. I must admit however, that the majority of people I've worked with would just add the getters and would not think about it in detail as you do.
Ok, so how do we solve the problem of persisting something we can't get access to? Well, just ask the object to persist itself.
You can have a persist() (or whatever) method on the object itself. This is ok, since it is part of the business. If it is not, think about what is. Is it sendToBackend() maybe? This does not mean you have to put the details of persistence into the object!
The method itself can be as removed from actual persistence as you like. You can give it interfaces as parameters, or it can return some other object that can be used further down the line.
See these other answers about the same problems for presentation:
Returning a Data Structure to Display information
Encapsulation and Getters
I have some confusion about use of Controller with Repository Pattern while maintaining SOLID Principle. Consider, I have two types of Quotations
Commercial Quotation
Private Quotation
And there is a high chance of new types of quotations in future. Each Quotations has different fields, business logics yet they share many common functions. So I created a QuotationInterface
Quotation Inteface
interface QuotationInterface
{
public function save(array $data);
}
Quotation class that implement the interface
class CommercialQuotation implements QuotationInterface
{
public function(array $data)
{
// save commercial quotation
}
}
class PrivateQuotation implements QuotationInterface
{
public function(array $data)
{
// save Private quotation
}
}
Quotation Repository
class QuotationRepository
{
public function save(array $data, QuotationInterface $quotation)
{
$quotation->save($data);
}
}
QotationController
public function store(Resource $resource)
{
$inputs = $resource->all();
/**
* Clearly here Open/Close Principle is broken
*/
if ($inputs['type'] == 'private'){
$quotation = new PrivateQuotation;;
}
else if($inputs['type'] == 'commercial'){
$quotation = new CommercialQuotation;
}
$this->repo->save($inputs, $quotation);
}
Here in my QuotationController, it is clearly violating Open/Close Principle..
Is it a good idea to Create a Controller for each type of quotation (might be 10+ some day, who know?) to avoid the OCP violation or my design is just wrong? Any suggestion, design change tips, resource are welcome.
NOTE: My Quotation Controller will have many other functions except the save only.
If you're going ahead the way you've shown, i suggest you to use a single controller for your quotations and use a Factory design pattern to create your $quotation objects
For example, with a simple factory like this:
//FACTORY CLASS
abstract class QuotationFactory
{
/** return QuotationInterface */
public static function createQuotation($type)
{
switch($type)
{
CASE "private":
return new PrivateQuotation();
break;
CASE "commercial":
return new CommercialQuotation();
break;
}
}
}
you could use the factory from you controllers' methods:
//YOUR CONTROLLER'S METHOD
public function store(Resource $resource)
{
$inputs = $resource->all();
//delegate objects creation to factory class
$quotation = QuotationFactory::createQuotation( $inputs['type'] );
$this->repo->save($inputs, $quotation);
}
This way you are not going to violate the open/closed principle in your controllers, because as you add quotations, you'll only need to modify the method of the factory (adding cases to the switch statement ), and it will return a QuotationFactory object wherever needed.
This will also keep your code DRY and SOLID because you don't have to repeat the if/else statements to create your objects in your controller's methods as you delegate the responsability of the objects' creation to a specific factory class
As correctly pointed ount in the comments below, the Simple factory is going to help you avoiding the Open/Closed Principle in your controllers but be ware that, from a more general point of view, the Simple Factory itself is inherently violating the OCP as it uses a switch case.
Anyway, from what i see of your application, the Simple factory could be a good solution, as your primary concern is to build in many places instances from a variable type. Thus, using the Simple factory you can 'hide' this process of creating objects into the factory and get the instances you need in your controllers. So you are violating the OCP only inside the factory in the switch case, but i think this could be a beareble trade-off
I think this mostly depends on the scope of your application. In the PHP world these days, people are so angry with if/else statements :). However, if that works for your application and seems reasonable in the scope of YOUR context, I think that's fine.
Businesses change and Business changes aren't always easy to plan for. You can only try to make those changes easier when they arise.
That being said, classes are cheap and I think that having separate classes at this point (and in the future) is very reasonable. If the requirements for each type of quotation expand, you'll be in good footing and I don't think you're abstracting so far that you're code will be difficult to understand.
I know it's late, but i hope my comment helps more people searching your issue.
You should follow the following principle:
"If you have a conditional like that you should do it in the low level abstraction not in the high level"
so the design should be:
class QuotationFactory
{
public static function make($type)
{
switch($type)
{
CASE "private":
return new PrivateQuotation();
CASE "commercial":
return new CommercialQuotation();
default:
throw new InvalidTypeException("Invalid type code.");
}
}
}
The above refactoring called "Replace conditional/type code with polymorphism".
If there're no new types in the future you should follow "Replace Parameter with explicit methods" refactoring, it would improve the readability.
For more you should read a book called "Refactoring: Improving the Design of Existing Code" by Martin Fowler.
I'm trying to follow the Law Of Demeter ( see http://en.wikipedia.org/wiki/Law_of_Demeter , http://misko.hevery.com/code-reviewers-guide/flaw-digging-into-collaborators/ ) as I can see the benefits, however I've become a little stuck when it comes to domain objects.
Domain objects do naturally have a chain and sometimes it's necessary to display the information about the entire chain.
For instance, a shopping basket:
Each order contains a user, delivery info and a list of items
Each order item contains a product and quantity
Each product has a name and price.
Each user contains a name and address
The code which displays the order information has to use all the information about the order, users and products.
Surely it's better and more reusable to get this information through the order object e.g. "order.user.address.city" than for some code higher up to do queries for all the objects I listed above then pass them into the code separately?
Any comments/suggestions/tips are welcome!
One problem with using chained references, such as order.user.address.city, is that higher-order dependencies get "baked into" the structure of code outside the class.
Ideally, in cases when you refactor your class, your "forced changes" should be limited to the methods of the class being refactored. When you have multiple chained references in the client code, refactoring drives you to make changes in other places of your code.
Consider an example: suppose that you'd like to replace User with an OrderPlacingParty, an abstraction encapsulating users, companies, and electronic agents that can place an order. This refactoring immediately presents multiple problems:
The User property will be called something else, and it will have a different type
The new property may not have an address that has city in cases when the order is placed by an electronic agent
The human User associated with the order (suppose that your system needs one for legal reasons) may be related to the order indirectly, - for example, by being a designated go-to person in the definition of the OrderPlacingParty.
A solution to these problems would be to pass the order presentation logic everything that it needs directly, rather than having it "understand" the structure of the objects passed in. This way you would be able to localize the changes to the code being refactored, without spreading the changes to other code that is potentially stable.
interface OrderPresenter {
void present(Order order, User user, Address address);
}
interface Address {
...
}
class PhysicalAddress implements Address {
public String getStreetNumber();
public String getCity();
public String getState();
public String getCountry();
}
class ElectronicAddress implements Address {
public URL getUrl();
}
interface OrderPlacingParty {
Address getAddress();
}
interface Order {
OrderPlacingParty getParty();
}
class User implements OrderPlacingParty {
}
class Company implements OrderPlacingParty {
public User getResponsibleUser();
}
class ElectronicAgent implements OrderPlacingParty {
public User getResponsibleUser();
}
I think, when chaining is used to access some property, it is done in two (or at least two) different situation. One is the case that you have mentioned, for example, in your presentation module, you have an Order object and you would like to just display the owner's/user's address, or details like city. In that case, I think it is of not much problem if you do so. Why? Because you are not performing any business logic on the accessed property, which can (potentially) cause tight coupling.
But, things are different if you use such chaining for the purpose of performing some logic on the accessed property. For example, if you have,
String city = order.user.address.city;
...
order.user.address.city = "New York";
This is problematic. Because, this logic is/should more appropriately be performed in a module closer to the target attribute - city. Like, in a place where the Address object is constructed in the first place, or if not that, at least when the User object is constructed (if say User is the entity and address the value type). But, if it goes farther than that, the farther it goes, the more illogical and problematic it becomes. Because there are too many intermediaries are involved between the source and the target.
Thus, according to the the Law of Demeter, if you are performing some logic on the "city" attribute in a class, say OrderAssmebler, which accesses the city attribute in a chain like order.user.address.city, then you should think of moving this logic to a place/module closer to the target.
You're correct and you'll most likely model your value objects something like this
class Order {
User user;
}
class User {
Address shippingAddress;
Address deliveryAddress;
}
class Address {
String city;
...
}
When you start considering how you will persist this data to a database (e.g. ORM) do you start thinking about performance. Think eager vs lazy loading trade offs.
Generally speaking I adhere to the Law of Demeter since it helps to keep changes in a reduced scope, so that a new requirement or a bug fix doesn't spread all over your system. There are other design guidelines that help in this direction, e.g. the ones listed in this article. Having said that, I consider the Law of Demeter (as well as Design Patterns and other similar stuff) as helpful design guidelines that have their trade-offs and that you can break them if you judge it is ok to do so. For example I generally don't test private methods, mainly because it creates fragile tests. However, in some very particular cases I did test an object private method because I considered it to be very important in my app, knowing that that particular test will be subject to changes if the implementation of the object changed. Of course in those cases you have to be extra careful and leave more documentation for other developers explaining why you are doing that. But, in the end, you have to use your good judgement :).
Now, back to the original question. As far as I understand your problem here is writing the (web?) GUI for an object that is the root of a graph of objects that can be accessed through message chains. For that case I would modularize the GUI in a similar way that you created your model, by assigning a view component for each object of your model. As a result you would have classes like OrderView, AddressView, etc that know how to create the HTML for their respective models. You can then compose those views to create your final layout, either by delegating the responsibility to them (e.g. the OrderView creates the AddressView) or by having a Mediator that takes care of composing them and linking them to your model. As an example of the first approach you could have something like this (I'll use PHP for the example, I don't know which language you are using):
class ShoppingBasket
{
protected $orders;
protected $id;
public function getOrders(){...}
public function getId(){...}
}
class Order
{
protected $user;
public function getUser(){...}
}
class User
{
protected $address;
public function getAddress(){...}
}
and then the views:
class ShoppingBasketView
{
protected $basket;
protected $orderViews;
public function __construct($basket)
{
$this->basket = $basket;
$this->orederViews = array();
foreach ($basket->getOrders() as $order)
{
$this->orederViews[] = new OrderView($order);
}
}
public function render()
{
$contents = $this->renderBasketDetails();
$contents .= $this->renderOrders();
return $contents;
}
protected function renderBasketDetails()
{
//Return the HTML representing the basket details
return '<H1>Shopping basket (id=' . $this->basket->getId() .')</H1>';
}
protected function renderOrders()
{
$contents = '<div id="orders">';
foreach ($this->orderViews as $orderView)
{
$contents .= orderViews->render();
}
$contents .= '</div>';
return $contents;
}
}
class OrderView
{
//The same basic pattern; store your domain model object
//and create the related sub-views
public function render()
{
$contents = $this->renderOrderDetails();
$contents .= $this->renderSubViews();
return $contents;
}
protected function renderOrderDetails()
{
//Return the HTML representing the order details
}
protected function renderOrders()
{
//Return the HTML representing the subviews by
//forwarding the render() message
}
}
and in your view.php you would do something like:
$basket = //Get the basket based on the session credentials
$view = new ShoppingBasketView($basket);
echo $view->render();
This approach is based on a component model, where the views are treated as composable components. In this schema you respect the object's boundaries and each view has a single responsibility.
Edit (Added based on the OP comment)
I'll assume that there is no way of organizing the views in subviews and that you need to render the basket id, order date and user name in a single line. As I said in the comment, for that case I would make sure that the "bad" access is performed in a single, well documented place, leaving the view unaware of this.
class MixedView
{
protected $basketId;
protected $orderDate;
protected $userName;
public function __construct($basketId, $orderDate, $userName)
{
//Set internal state
}
public function render()
{
return '<H2>' . $this->userName . "'s basket (" . $this->basketId . ")<H2> " .
'<p>Last order placed on: ' . $this->orderDate. '</p>';
}
}
class ViewBuilder
{
protected $basket;
public function __construct($basket)
{
$this->basket = $basket;
}
public function getView()
{
$basketId = $this->basket->getID();
$orderDate = $this->basket->getLastOrder()->getDate();
$userName = $this->basket->getUser()->getName();
return new MixedView($basketId, $orderDate, $userName);
}
}
If later on you rearrange your domain model and your ShoppingBasket class can't implement the getUser() message anymore then you will have to change a single point in your application, avoid having that change spread all over your system.
HTH
The Law Of Demeter is about calling methods, not accessing properties/fields. I know technically properties are methods, but logically they're meant to be data. So, your example of order.user.address.city seems fine to me.
This article is interesting further reading: http://haacked.com/archive/2009/07/13/law-of-demeter-dot-counting.aspx
What's the name of the antipattern where methods take a generic god-object that has every property you might ever need for a method, rather than explicitly declaring what the method needs?
Eg:
public class BaseRequest
{
User user;
Car car;
CustomerRecords customerRecords;
Folder folder;
// ... etc for 10 - 20 other unrelated parameters
}
public void doSomething(BaseRequest request)
{
User user = request.getUser();
// do stuff with user, ignore all other attributes of request
}
Instead of
public void doSomething(User user)
{
// do stuff with user, since it's nice and clear what we want
}
Note - I'm not referring to the Single Responsibility Princple which BaseRequest violates. Instead, I'm looking for the name of the antipattern where the method signature is "lying" about its dependencies.
Also, are there any good blog posts that succinctly explain the evilness of this pattern, which I can point someone to?
Law of Demeter violation
I would say it's just an effect of having the god object. The problem shouldn't exist when the god object doesn't exist.