Implementing Persistence in Clean Architecture

1,160 views
Skip to first unread message

Christian B

unread,
Feb 20, 2014, 11:25:32 AM2/20/14
to clean-code...@googlegroups.com
Hello,

So i am currently playing around with Uncle Bobs Clean Architecture.

I've understand, that you should start with the Usecases and Entities. 

I've build some of them now, but i am still wondering, where to create the for instance Repository class in an application?

Say, we have: MysqlOrderRepository for the application, and an MockOrderRepository for test purposes. WHERE do i create that Repository?

When i think about it, i come up with 2 possible ways:

1. Create it at the delivery mechanism (web, console), wrap it with some other data in a Request Model, pass it through the boundary to the interactor.
2. Create it at the Interactor, but this could make testing a little tricky


Martin Lee

unread,
Feb 20, 2014, 4:15:39 PM2/20/14
to clean-code...@googlegroups.com
A repository is quite a concrete thing in an application. Since dependencies should point away from concrete towards the abstract, a concrete entity should be created from an even more concrete place. Possibly main().
If you were going to change your application to use flat-file repo, which layer would NEED to know that? 

James Green

unread,
Feb 21, 2014, 3:49:39 AM2/21/14
to clean-code...@googlegroups.com
Agree with Martin. The application needs an OrderRepository (abstract or interface). Implementing this in a MySQLPersistence module that depends on your application will be a MySQLOrderRepository extending or implementing OrderRepository.

I'm sure if the above you already realise. The other way of interpreting your question is where to create the concrete instance for client use. The client will likely be the interactor, and the client receives it through dependency injection (by main() or a framework).

If in your application you have something that needs repository access, you need to supply a MockOrderRepository as you have already stated. Testing of the interactors may also require this...

That's my understanding and I accept corrections :)



--
The only way to go fast is to go well.
---
You received this message because you are subscribed to the Google Groups "Clean Code Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discu...@googlegroups.com.
To post to this group, send email to clean-code...@googlegroups.com.
Visit this group at http://groups.google.com/group/clean-code-discussion.

daniphp

unread,
Mar 2, 2014, 2:11:03 PM3/2/14
to clean-code...@googlegroups.com
So each time we create a concrete repository we also need an interface for it? I'm not comfortable with this.

My solution is to create e concrete repository in the Interactor constructor if a repository is not passed as a parameter(useful for testing).

Mark Badolato

unread,
Mar 2, 2014, 3:00:42 PM3/2/14
to clean-code...@googlegroups.com
On Sun, Mar 2, 2014 at 12:11 PM, daniphp <dan...@gmail.com> wrote:
So each time we create a concrete repository we also need an interface for it? I'm not comfortable with this.

Why not? Using a contrived and simplified  example (in PHP):

interface OrderRepository
{
    findAll();
    findById($id);
    // ...
}

...

Repository/
    FileSystem/
        FileSystemOrderRepository  <-- Implements the OrderRepository interface
    InMemory/
        InMemoryOrderRepository  <-- Implements the OrderRepository interface
    MySQL/
        MySQLOrderRepository  <-- Implements the OrderRepository interface
    Mock/
        MockOrderRepository  <-- Implements the OrderRepository interface


My solution is to create e concrete repository in the Interactor constructor if a repository is not passed as a parameter(useful for testing).

The interactor's constructor only needs to know about the interface. You can change which concrete repository you pass to it at will. 

As you said, passing it is useful for testing, but it's also a cleaner solution. If you instantiate a concrete repository in the class, you've coupled that class to the repository and made it a lot harder to test your code independent of the dependencies.

class CreateOrderInteractor
{
    public __constructor(OrderRepository $repository, ...)
    {
        // ...
    }
}

class OrderTest extends \PHPUnit_Framework_TestCase
{
    /** @test */
    public function create()
    {
        $interactor = new CreateOrderInteractor(new MockOrderRepository());
        // ...
    }
}



--
Mark Badolato 

Twitter: @MarkBadolato

Martin Lee

unread,
Mar 2, 2014, 6:30:52 PM3/2/14
to clean-code...@googlegroups.com
the assumptions you seem to make are:
- that a concrete repository needs a different interface for each implementation; 
- and/or, that one concrete repository cannot implement several interfaces;
- and, creating an interface is expensive 

the InterfaceSegregationPrinciple would (to me) suggest that creating one interface for each category of use is better. Callers should know only about the methods they need. The implementation may or may not also implement other interfaces.

a repository implementation should be partitioned into interfaces according to the categories of use.

this allows you to concentrate on the responsibilities the repo has (including efficient resource use) in the concrete repo implementation, and the callers need know nothing_at_all about which concrete repo is in use (LiskovSubstitutionPrinciple)




On Mon, Mar 3, 2014 at 6:11 AM, daniphp <dan...@gmail.com> wrote:
So each time we create a concrete repository we also need an interface for it? I'm not comfortable with this.

My solution is to create e concrete repository in the Interactor constructor if a repository is not passed as a parameter(useful for testing).

--
The only way to go fast is to go well.
---
You received this message because you are subscribed to a topic in the Google Groups "Clean Code Discussion" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clean-code-discussion/hawFYqHx3fw/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clean-code-discu...@googlegroups.com.

Luis Cordova

unread,
Mar 2, 2014, 9:43:26 PM3/2/14
to clean-code...@googlegroups.com
I think Martin and Mark's responses are in the right direction. I did not know if Martin was responding to Mark or to the first opening post. I want to believe their responses are combined. am I right?

if so all good :)


You received this message because you are subscribed to the Google Groups "Clean Code Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discu...@googlegroups.com.

daniphp

unread,
Mar 3, 2014, 3:29:21 AM3/3/14
to clean-code...@googlegroups.com
Mark, your examples are correct but a bit to didactic. In practice you rarely need a FileSystemOrderRepository and a MySQLOrderRepository for each Repository.
you usually have concrete implementation and until you truly need an OrderRepository interface you are breaking YAGNI just because you "might" need it. In dynamic typed languages even Uncle Bob sometimes suggests(if I'm not mistaken) that interfaces do not play such an important role.

MockOrderRepository is again a bad practice because you need to mock the Repository using a mocking framework not creating concrete classes.

While I do agree with you on the entire comment I would debate further on the need for an interface if you only use a single concrete implementation. Would you create 100 interfaces for 100 repositories if there is no need for multiple concrete implementations, especially in dynamic typed languages?

Sebastian Gozin

unread,
Mar 3, 2014, 4:31:22 AM3/3/14
to clean-code...@googlegroups.com
You may rarely need 2 or more implementations of the same repository but you do often need the ability.

So in a dynamic language like PHP that means you don't need an interface. In a language like Java it can be a bit more tricky. You certainly don't want to statically wire against a MySQLOrderRepository but I suppose you could wire against an OrderRepository which happens to be implemented using MySQL and once you need FSOrderRepository you could rename it introduce the interface and everything will probably work if none of the client code depends on implementation details from the mysql implementation.

I've learned to be wary of people touting YAGNI as it's often used as an excuse for violating SOLID.
To me YAGNI means, do not implement FS, mysql, mongo, cassandra and elasticsearch order repository but pick one of them and make sure you can still swap when needed.

daniphp

unread,
Mar 3, 2014, 4:37:37 AM3/3/14
to clean-code...@googlegroups.com
How would you apply your vision on database centric applications?

You have for example a user table, a job table and a language table.
You will need a repository for each of them and won't have any common interface.

Sebastian Gozin

unread,
Mar 3, 2014, 4:42:48 AM3/3/14
to clean-code...@googlegroups.com
What about?

interface Repository<T> {
  T get(id)
  void save(data)
  void delete(id)
  Iterable<T> find(query, args)
}

Doesn't that cover most things you would want to do with either of those types?
Should you need something even more specific you can introduce another interface which extends this one.

daniphp

unread,
Mar 3, 2014, 5:02:04 AM3/3/14
to clean-code...@googlegroups.com
Sebastian, while I do appreciate your answer, I personally am interested in your actual production implementations.

I think the interface usage example is a bit more generic, and in my experience I use this logic:
- if I expect the concrete implementation would vary then I will of course use an interface
- if there is not future or previous reason to create an interface I would simply not create one

I understand this might not be a good approach and I can see why Uncle Bob creates interfaces to communicate across boundaries but a Repository will be created in the Interactor.

But to make this short, your suggestion is to create interfaces for any repository even if there is a single concrete implementation just to have the possibility in the future(even if not predictable) to respect Dependency Inversion Principle?

"To me YAGNI means, do not implement FS, mysql, mongo, cassandra and elasticsearch order repository but pick one of them and make sure you can still swap when needed."
No, when you almost KNOW you will use FS, mysql, mongo or cassandra then you come back to the code and implement the interfaces but not from the start, that's my interpretation of YAGNI.


theUniC

unread,
Mar 3, 2014, 4:10:45 AM3/3/14
to clean-code...@googlegroups.com
@daniphp

So then, you're establishing the high policy based on concrete implementations, breaking the Dependency Inversion principle. Usually when I code I start by using in-memory repositories in my tests. This leads me to define the repositories interfaces I need. When I finish designing all the behaviour of my use-case and I need to integrate all the systems, usually I create a concrete repository implementation based on the persistence layer I'm working with. For all this I need some kind of interface, explicit or not.

Cheers,
Christian.


--

theUniC

unread,
Mar 3, 2014, 5:35:43 AM3/3/14
to clean-code-discussion
@daniphp

It's not about violating the Dependency Inversion principle per se. I think it's all about the intention behind. Simply I don't like to depend upon concrete implementations because then my code becomes too rigid. And you always define interfaces, even when you're not declaring it explicitly.

Althought I agree YAGNI is an important concern to worry about, IMHO it's more important that my code and my architecture becomes really clean :)

Cheers,
Christian.


--
The only way to go fast is to go well.
---
You received this message because you are subscribed to the Google Groups "Clean Code Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discu...@googlegroups.com.

witali mik

unread,
Mar 3, 2014, 6:18:53 AM3/3/14
to clean-code...@googlegroups.com
@Christian B

I create the concrete Repository/Adapter implementations within the Framework. Most of PHP Frameworks includes some bootstraping files where "Stuffs" are initialized. Thats the Part where you can do this. (I assume you use PHP cause of other your post)

In my Project, where i currently learn the Architecture, i inject the classes into Dependency Injection Container

https://github.com/Opentribes/Core/blob/develop/app/Module.php#L48

Currently there are just view Dependencies, but later there will be more of them, so i will somehow refactor this part and split it up. (also i didnt created concrete implementations, just injected my mocked classes to create the gui)

https://github.com/Opentribes/Core/blob/develop/app/Module.php#L83

this is the part where i use my interactors inside the controller. as you can see, i get the classes from my dependency container und inject them into my interactor. (i used in this case the word Context, because my Registration Process would make too many things and would not fit the single responsiblity princip anymore, so i kinda grouped interactors into a context)

later i might want to create a use as administrator roles, so i would reuse the interactors in another context.
To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discussion+unsub...@googlegroups.com.

theUniC

unread,
Mar 3, 2014, 6:49:37 AM3/3/14
to clean-code...@googlegroups.com
@witali

I really believe it's not about a concrete technology. I think what we're discussing applies to design in general. All you expose is correct from my POV. Your example exposes way clear how the underlying framework is using your domain model, which I think it's good from the architecture perspective. Like some of us are telling, you are not wiring your domain model use-cases upon concrete implementations


In that case you're explicitly declaring the interface which all the concrete user repository implementations must adhere, which I think it's perfectly fine.


:)


To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discu...@googlegroups.com.

daniphp

unread,
Mar 3, 2014, 6:52:40 AM3/3/14
to clean-code...@googlegroups.com
Great inside Christian,
I really like you explanation but you see you are actually using two distinct concrete implementation and I'm not against that.

But you see, you got here because of TDD, you needed the in memory persistence for your tests. But usually what I see in practice is devs using the interface without no intent of using more then 1 concrete implementation. 

Also principle can be broken, if you understand the benefits in some cases.

witali mik

unread,
Mar 3, 2014, 6:56:37 AM3/3/14
to clean-code...@googlegroups.com
Thx, I just wanted to(or tryed at least) to reply to Christian B's original Question. The further i read in this forum, the more it looks like out of topic. since the discussion changed into "how much abstraction do i need vs YAGNI"

@Christian today afternoon iam going to create the Concrete implementation, hope then it will be clearer or hope someone would/could review it, so i can improve my skills
To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discussion+unsubscri...@googlegroups.com.
To post to this group, send email to clean-code...@googlegroups.com.

daniphp

unread,
Mar 3, 2014, 7:01:30 AM3/3/14
to clean-code...@googlegroups.com
To get back to the topic, the concrete Repository should be created inside the Interactor, not inside the MVC controller.
Any disagreement?

James Green

unread,
Mar 3, 2014, 7:05:41 AM3/3/14
to clean-code...@googlegroups.com
That's my understanding. Bearing in mind it is also my understanding that an MVC Controller class can extend an application interactor class (deferring to the superclass methods)...


--
The only way to go fast is to go well.
---
You received this message because you are subscribed to the Google Groups "Clean Code Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discu...@googlegroups.com.

theUniC

unread,
Mar 3, 2014, 7:06:43 AM3/3/14
to clean-code-discussion
@witali

Agreed. I thought, until sent the reply, that you were replying my response, and my intention wasn't to continue deviating from the topic. No time to undo. Must apologize.

@daniphp

Agreed. :)


To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discu...@googlegroups.com.

daniphp

unread,
Mar 3, 2014, 7:08:21 AM3/3/14
to clean-code...@googlegroups.com
I did not find an actual example from Uncle Bob but I think a Controller should only USE an Interactor.

witali mik

unread,
Mar 3, 2014, 7:08:59 AM3/3/14
to clean-code...@googlegroups.com
I disagree,

Frameworks itselfs offers you abstract implementations. For example Doctrine Abstract Layer. As uncle bob says "Date the Framework, dont marry it" which tells, you schould use a framework, but your application should not be dependant on it.

well it is not possible to create 100% independance while using a framework, however, you can put all stuffs where a framework may offer helper functions into one place. So when you change the entire framework. you know exactly what you can change since the things are at one place.

Also i agree that repositories should not be created inside MVC. thatswhy i told about bootstrap. thats the stuff inbetween the MVC and your Domain logic

James Green

unread,
Mar 3, 2014, 7:11:46 AM3/3/14
to clean-code...@googlegroups.com
I'm sure I read somewhere someone stating that a controller is an interactor. Clarification welcomed.


witali mik

unread,
Mar 3, 2014, 7:11:58 AM3/3/14
to clean-code...@googlegroups.com
Forgot to mention:

your interactor should not care, where your entities are stored.. if the interactor doesnt care, why do you need an interface for each storage?


witali mik

unread,
Mar 3, 2014, 7:25:46 AM3/3/14
to clean-code...@googlegroups.com

Well basicly youre right. But some Frameworks, does not Offer you just to create a route which executes your interactor. In this case, you have to call the interactor within your controller /action.

James Green

unread,
Mar 3, 2014, 7:28:15 AM3/3/14
to clean-code...@googlegroups.com
If the framework demands you build controllers extending their own base classes then you have no choice. Is that what you mean?


--

witali mik

unread,
Mar 3, 2014, 7:29:25 AM3/3/14
to clean-code...@googlegroups.com

I would not recommend extend controller from interactor, instead inject the interactor into controller, so you can eventually replace it on runtime over plugins for example(allows you to modify the behavior of a route by modules/plugins)

witali mik

unread,
Mar 3, 2014, 7:33:22 AM3/3/14
to clean-code...@googlegroups.com
Exactly, the purpose of a framework is to give you some basic structure where you can quick develop your application. If your framework doesnt offer this, you have to create custom structure and custom bootstrapping stuffs.

Basicly i think, it depends on the framework you use, how to use the interactors(within controller actions or directly)

You could also write custom controllers.. but there is no reason for this(unless youre building your custom framework)

James Green

unread,
Mar 3, 2014, 7:47:36 AM3/3/14
to clean-code...@googlegroups.com
If the "application" code is in the application interactor there is no reason not to extend this within your REST (for instance) module and extend it.

Example:

PersonInteractor inside the application deals with receiving PersonRequests and respond with PersonReports.

PersonRest inside the web module extends PersonInteractor. It accepts Person of type local to the web module. It maps this local Person to the relevant PersonRequest and calls a super.method(). The response may be inspected and perhaps mapped to a local PersonResponse and returned to the caller.

There is of course also the option that a PersonInteractor instance is injected into PersonRest. Engineering of the two will likely dictate which pattern to use.



witali mik

unread,
Mar 3, 2014, 7:53:31 AM3/3/14
to clean-code...@googlegroups.com
Well I dont know which Language do you use.

But in PHP, the only one difference if you open the URL /user/get/someinfo is the way how you display it.

so for example in my case, I have just one interactor which process request object and returns response object. so i can call after my interactor echo json_encode($response) or echo $templateEngine->render('template',$response);

i dont need to extend it from some rest controller or stuff like that, just call interactor and make different output depending on other stuffs(for example the URL)
To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discussion+unsub...@googlegroups.com.

witali mik

unread,
Mar 3, 2014, 8:05:06 AM3/3/14
to clean-code...@googlegroups.com
i made view days ago a small application without a framework, as router, i used the apache internal routing

http://pastebin.com/rfuLKU2D

each file which were linked just had 4 lines of code (+ some more lines to pass all request arguments into interactor request)

if i would be allowed to use a framework, i would just copy those view lines inside the framework controller

Caio Fernando Bertoldi Paes de Andrade

unread,
Mar 3, 2014, 8:29:19 AM3/3/14
to clean-code...@googlegroups.com
This misunderstanding seems to be caused by the cultural difference between PHP and Java. PHP's culture has apache doing the routing and starting new PHP processes to handle each request. On the other hand, Java's culture has a Java server process creating new threads to handle requests.

Since Java creates threads, it can share memory amongst them, it can share main's decisions. Main creates a gateway, registers it in the factories and then all threads have access to it. So it's easy for Java people to understand where the concretions are created.

PHP is a bit trickier. You don't have such sharing of decisions. Each new request has to decide which concretions to use all over again. To me, the cleaner approach is to have your endpoints ask for the concretions to a Boostrap class whose responsibility is to decide which ones to create (i.e. configuration).

I hope this helps to improve the discussion,
Caio

Sent from Mailbox for iPhone


To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discu...@googlegroups.com.

To post to this group, send email to clean-code...@googlegroups.com.
Visit this group at http://groups.google.com/group/clean-code-discussion.

--
The only way to go fast is to go well.
---
You received this message because you are subscribed to the Google Groups "Clean Code Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discu...@googlegroups.com.

James Green

unread,
Mar 3, 2014, 10:03:32 AM3/3/14
to clean-code...@googlegroups.com
It's not so much about the threading model (which costs non-container based languages such as PHP time). In Java we get a container for in-memory caching, and dependency injection from a framework that often heavily relies on this cache. PHP is much more procedural by nature - the DI frameworks I've seen for PHP look quite thin by comparison.

Ideally the interactor within the application will get it's repositories by injection (perhaps indirectly, see below). With PHP there may be a need to call out to a something that maintains a list of current implementations I guess.

I just checked - the PHP applications we have use Zend Framework. In these cases our controllers must extend Zend_Controller_Action, thereby forcing us to acquire through some proxy a reference to an interactor. With Java we can extend our interactors with framework enhanced web controllers that perform the dependency injection. Same for a CLI. Either way application level code does not depend on detail until runtime when something must decide and make resources available.

Reply all
Reply to author
Forward
0 new messages