Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Yes, this is absolutely fine approach. And yes, sometimes you can use constructor injection, nothing wrong with that too. But with constructor injection you have to propagate your dependencies <em>manually</em>, while with cake pattern your dependencies are propagated <em>automatically</em> via self-type annotations. So for big projects constructor injection actually lead to more boilerplate than cake pattern, especially at the construction site (where you create all your objects and set up dependencies between them).</p> <p>However, what you have presented is not full-fledged cake pattern. In real cake pattern there is an additional layer around business logic classes, so-called components, and you do not wire up logic classes directly but components instead.</p> <pre><code>trait FileStorageComponent { def fileStorage: FileStorage trait FileStorage { def readFile(filename: String): OutputStream } } trait S3FileStorageComponent extends FileStorageComponent { val fileStorage = new S3FileStorage class S3FileStorage extends FileStorage { def readFile(filename: String): OutputStream = ??? } } trait FileHttpServerComponent { self: FileStorageComponent =&gt; val fileHttpServer = new FileHttpServer class FileHttpServer { def fetchFile(session: Session, filename: String) = ??? } } // Wiring object S3FileHttpServer extends FileHttpServerComponent with S3FileStorageComponent // Anonymous val server = new FileHttpServerComponent with S3FileStorageComponent // Mocking object TestFileHttpServer extends FileHttpServerComponent with FileStorageComponent { val fileStorage = mock[FileStorage] } </code></pre> <p>In this approach there are more boilerplate in traits definitions, but in return you have greater flexibility and very clear dependency management on the use place. For example, here is how program entry point in one of my projects looks like:</p> <pre><code>object Main extends MainUI with DefaultActorsManagerComponent with DefaultPreferencesAccessComponent with DefaultModelComponent with DefaultMainWindowViewComponent with DefaultMainWindowControllerComponent with MainWindowReporterComponent with DefaultClientActorComponent with DefaultResponseParserActorComponent with DefaultArchiverActorComponent with DefaultMainWindowAccessActorComponent with DefaultUrlParserComponent with DefaultListenerActorComponent with DefaultXmlPrettifierComponent </code></pre> <p>All main program components are in one place. Pretty neat IMO.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload