Search code examples
ooparchitectureclean-architecturefacade

Which Clean Architecture layer do factories belong to?


I suppose the title speaks for itself but in which layer of Clean Architecture do you typically put factories?

If the factory interface does not go in the same layer as the implementation I would like to know this also.

Thanks!


Solution

  • In which layer of Clean Architecture do you typically put factories?

    A factory is a concept that does not belong to one architectural layer. You can use it whereever you want to decouple one layer or architectural boundary from another.

    It is used when a client in one architecturaly context needs to instantiate objects of another architectural conext that it should not depend on. E.g. entities use framework or library objects.

    It is also often used by the application startup or main component. For details take a look here.

    If the factory interface does not go in the same layer as the implementation I would like to know this also.

    The interface is often placed beside the client that uses it, because an interface is made for a client and not an implementor. A client needs someone to do something. Therefore the client tells what it wants with an interface. The implementor shows how it is done.

    +--------+        ||    
    | client |        ||    
    +--------+        ||
         |            ||
         V            ||
    +-----------+     ||         +-------------+
    | Interface |   <-||---      | Implementor |
    +-----------+     ||         +-------------+
    
    || = architectural boundary
    

    Sometimes you want to have an interface that serves many clients in different architectural contexts. Then you can either separate the interface from both contexts.

    +----------+     ||
    | client 1 |     ||
    +----------+     ||
                     ||
          |          ||
    ======|==========||=================
          |          ||
          V          ||      
                     ||           
    +-----------+    ||     +-------------+
    | Interface | <-------- | Implementor |
    +-----------+    ||     +-------------+
                     ||
          ^          ||
          |          ||
    ======|==========||==================
          |          ||
                     ||
    +----------+     ||
    | client 2 |     ||
    +----------+     ||
    

    or you can use separate interfaces for each client and let the implementor implement both.

    +----------+     ||
    | client 1 |     ||
    +----------+     ||
          |          ||
          V          ||
    +-----------+    ||     
    | Interface | <---------------+
    +-----------+    ||           |
                     ||     +-------------+
    =================||     | Implementor | 
                     ||     +-------------+
    +-----------+    ||           |
    | Interface | <---------------+
    +-----------+    ||     
          ^          ||
          |          ||
    +----------+     ||
    | client 2 |     ||
    +----------+     ||
    

    You can also use 2 implementors. One for each interface.