Clean Architecture... Say What Now?

942 views
Skip to first unread message

Terence McGhee

unread,
Jul 10, 2013, 11:17:51 AM7/10/13
to clean-code...@googlegroups.com
Ok, here's what I think I understand so far. Please correct what I have wrong and fill in any gaps.

Btw, my development environment is C# and Visual Studio.

When trying to architect my app after the model described in episode 7, here's what I think I know:
  1. The UI / delivery mechanism will be a plugin to my app.
  2. My app is a series of Use Cases implemented in Interactor objects.
  3. The UI / delivery mechanism will communicate with my app through Boundary objects
  4. A single Boundary object is really 2 Interfaces. One for Request and one for Response.

Here's what I don't understand:

  1. Can I have a different Boundary for each Interactor?
  2. Is each Interactor a separate project in Visual Studio? In my first attempt, I created one class library project that contained all of the Interactors and Boundaries.
  3. Unless each Interactor is a separate project, why would I need an IOC container (or builders and factories) in main (or in my delivery mechanism) to access the Interactors?
    • IOW, why can't I just access the exact Boundary that I need for the Use Case Interactor that I know I want to call?
  4. This one is hard for me to put into words, but I'll give it a shot:
    In the request Boundary, it seems like the return value of the function call to the Interactor can be the data structure that would come back in the Response Boundary. As such, I don't see the need for the Response Boundary/Interface. I mean why create an interface instead of just returning the exact data structure that I want? And if I did create that Response Interface, it still seems like the methods in the Request Interface would return an instance of the Response Interface. Hopefully the code snippet below can help clarify my question.
interface CreateAccountRequestBoundary
{
   
OutputResponseBoundary CreateAccount()
}

interface CreateAccountResponseBoundary
{
   
bool didSucceed;
   
List<String> errorsEncounteredDuringCreationAttempt;
}




I'd really appreciate any and all help.

Thanks!!

Uncle Bob

unread,
Jul 11, 2013, 5:48:49 PM7/11/13
to clean-code...@googlegroups.com
Interactors implement the input boundary interface and use the output boundary interface.  The output boundary interface is implemented by a presenter.  

There is typically one input boundary interface and one output boundary interface per interactor.  So three classes per interactor (not to mention the presenter).

No, the interactor is not a separate project.  Projects are DLLs.  DLLs are components that we want to be independently deployed.  If two things are deployed at the same time, they might as well be in the same DLL.  There's no point is separating DLLs unless you plan to deploy them separately.

If a project contains a group of interactors, that project should also contain the boundary interfaces.  Typically the presenters and controllers would go in a different project.  So would the database implementations.  And so would the entities.

The controller calls the boundary for the interactor.  Since the interactor implements that boundary, the controller needs access to the interactor instance.  But we don't want the controller to know about the interactor directly.  So we use a factory.

You'll find more detailed answers to your questions in the episodes about the Component Principles, especially Episodes 14 & 18.


Terence McGhee

unread,
Jul 15, 2013, 3:36:03 PM7/15/13
to clean-code...@googlegroups.com
Thanks so much (again) for taking the time to reply to these topics.

Ok, based on what you said, here are a couple more questions I have.


 The output boundary interface is implemented by a presenter. 
All I can see in this interface is one (or more) data structures. I'm having a hard time envisioning any methods that could be placed here. Especially if following the "Tell Don't Ask" principle, I tell the input Boundary to do something and it returns without an exception or I ask it for something and it returns what I asked for. Either way, I can only imagine the output Boundary interface containing data structures and no methods. As such, I'm having a hard time understanding why it (the output boundary interface) needs to be an interface at all. Why not just the data structure itself?


But we don't want the controller to know about the interactor directly.
Aha! This was the part that had me stuck. As I was writing the failing tests, I would access my Interactors directly in an attempt to test them. Since I wanted to use my tests as the documentation for my clients, I wanted my controllers to look very similar to my tests.

Now I understand that I actually need to test two different things. I need unit tests for my Interactors and I also will need a set of unit tests for my factories et al.

Thanks!!

Gonna try this again, now!

Uncle Bob

unread,
Jul 17, 2013, 8:32:45 AM7/17/13
to clean-code...@googlegroups.com


On Monday, July 15, 2013 2:36:03 PM UTC-5, Terence McGhee wrote:

 The output boundary interface is implemented by a presenter. 
All I can see in this interface is one (or more) data structures. I'm having a hard time envisioning any methods that could be placed here. Especially if following the "Tell Don't Ask" principle, I tell the input Boundary to do something and it returns without an exception or I ask it for something and it returns what I asked for. Either way, I can only imagine the output Boundary interface containing data structures and no methods. As such, I'm having a hard time understanding why it (the output boundary interface) needs to be an interface at all. Why not just the data structure itself?

You might imagine a stateless interface in which the interactor decides what kind of response to create based on the outcome of the use case.  There might be several different valid responses, and several different alerts or responses to invalid data.  Each of those responses could be communicated to the presenter by calling a different method on the presenter (through the output boundary of course).

Terence McGhee

unread,
Jul 17, 2013, 9:43:38 AM7/17/13
to clean-code...@googlegroups.com
OMG, I think the light just came on! Oh man this is finna be awesome when I finish it! MUHAHAHA!


--
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/nekZdSK1vaw/unsubscribe.
To unsubscribe from this group and all its topics, 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.
 
 



--
Terence

Frederik Krautwald

unread,
Jun 18, 2014, 2:59:03 PM6/18/14
to clean-code...@googlegroups.com
The controller calls the boundary for the interactor.  Since the interactor implements that boundary, the controller needs access to the interactor instance.  But we don't want the controller to know about the interactor directly.  So we use a factory.

Where does that factory live and how does the controller get a hold of the factory? 
Reply all
Reply to author
Forward
0 new messages