Skip to content

Instantly share code, notes, and snippets.

@BlackScorp
Last active January 29, 2020 19:15
Show Gist options
  • Save BlackScorp/9626669770521647f404 to your computer and use it in GitHub Desktop.
Save BlackScorp/9626669770521647f404 to your computer and use it in GitHub Desktop.
clean code

#once upon a time...

there was a developer, he had to realize a nice clean greenfield project with any framework he like.

He had no idea which PHP Frameworks were outside there and after a small research he decide to use Kohana 3.2 because at this time this was the only one framework which the developer could understand and use.

after 9 months of developing the project was born and launched. the developer realized that a new version of the Kohana framework was released, it was a minor release.

one small simple update to Kohana 3.3 and the entire project was broken, he reverted the framework update.

after doing view more researches the developer realized that this problems have every framework, there are tons of blog posts, articles etc outside on the internet about upgraiding current code base of framework x to newer version(eg Zend 1 to Zend 2, Symfony 1 to Symfony 2 and so on)

Conclusion of this, frameworks are nice and you can speed up initial development, but on the other hand you either stuck to a version or to the framework and have to maintain this project while other frameworks offer much cooler features in the meantime.

Also many companies using their custom in house created framework(for what ever reason)

#Clean Code Architecture

How can you develop a software which is independant of the framework and at same time using features from a framework?

Robert C Marin presented a solution "Clean Code Architecture" Clean Code Architecture

The goals and idea behind it looks very nice but hard to understand in the first time there are many interpretations about it on the internet. I tryed to realize it in the easist way i could understand.

#Design Pattern First of all forget about all design pattern, the design pattern are realized by the framework, only view of them are used in the clean code architecture.

In all my projects i realized with the clean code architecture i used mostly Command Design Pattern and Repository Design Pattern

##Repository Design Pattern

a small note, many developers argued against it, because they never had to switch the database and the realization of this pattern would just take more time.

yes they are right, it is rarely that you have to change the database, however, a Repository is a container of data(or Datasource), which means, it could be also the Filesystem, an API even LDAP is a repository. While i had not to switch the Databases in my Projects still i had to add additional resources for data(Login via LDAP and/or Facebook API), display Profilepictures from Filesystem or gravatar API and so on.

Just want to say, Database is NOT the one and only datasource for an application

#PHP

So how to realized Clean Code Architecture in PHP? There are view small Rules.

  1. Every action on your website is realized by a Command Pattern(even simple CRUD action, you never know if you have to add additional logic later)
  2. Every action has its own Request and Response class
  3. All dependencies are injected and contains an interface, dont inject concrete classes

Personally i changed some definitions in my code to make it more understandable for or developers.

#Example

Lets start with a small example. Lets say we have to create a guestbook we would have 2 Features

  1. Create new entry
  2. List entries
<?php
//src/UseCase/CreateEntryUseCase.php
namespace GuestBook\UseCase;
class CreateEntryUseCase{
	public function process($request,$response){
	}
} 
//src/UseCase/ListEntriesUseCase.php
namespace GuestBook\UseCase;
class ListEntriesUseCase{
	public function process($request,$response){
	}
}

Thats it we got our basic classes well Command Design Pattern says that the methodname usually called execute, since i passed request and response inside, it feels like the name "process" will be better readable

Next step is to create Request and Response classes

<?php
//src/Request/CreateEntryRequest.php
namespace GuestBook\Request;
class CreateEntryRequest{}
//src/Request/ListEntriesRequest.php
namespace GuestBook\Request;
class ListEntriesRequest{}
//src/Response/CreateEntryResponse.php
namespace GuestBook\Response;
interface CreateEntryResponse{}
//src/Response/ListEntriesResponse.php
interface ListEntriesResponse{}

If you realized, the Responses are Interfaces, the reason for this iam going to explain later. For now lets add Typehints to our usecases

<?php
//src/UseCase/CreateEntryUseCase.php
namespace GuestBook\UseCase;
use GuestBook\Request\CreateEntryRequest;
use GuestBook\Response\CreateEntryResponse;
class CreateEntryUseCase{
	public function process(CreateEntryRequest $request,CreateEntryResponse $response){
	}
} 
//src/UseCase/ListEntriesUseCase.php
namespace GuestBook\UseCase;
use GuestBook\Request\ListEntriesRequest;
use GuestBook\Response\ListEntriesResponse;
class ListEntriesUseCase{
	public function process(ListEntriesRequest $request,ListEntriesResponse $response){
	}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment