Re: [scala-language] The cake’s problem, dotty des ign and the approach to modularity.
Justin du coeur <[email protected]>
| Newsgroups | gmane.comp.lang.scala |
|---|---|
| Message-ID | <CAO26FW1EuU_5+8vLQLx6cM9YsTceOMbNH3H4Gw35BJSjLDsWWg@mail.gmail.com> |
On Tue, May 12, 2015 at 1:58 PM, Jon Pretty <[email protected]> wrote: > This adds little over what Martin said, but for me, the general problem > with the Cake Pattern is the other side of the same coin that makes it so > convenient: that it is very easy to introduce new dependencies. > > It's very convenient when constructing a cake that you don't have to > define interfaces before you use them, and still have soundness enforced at > compile time. But this does nothing to promote well-designed or clean > interfaces, and consequently they don't arise naturally. Should you ever > have to untangle a cake during a refactoring, you will probably find it > unpleasantly difficult. > +1. As Querki grew from a nice little prototype into a fairly complex application (28k SLOC on the server, 50+ major functional areas, heavily inter-related), I grew more and more dissatisfied with simple-seeming answers like the Cake pattern, which turned out to be easier to write than maintain. Frankly, I wound up backing off to the same "Ecology Pattern" -- basically a variant of the Resource Locator / Dependency Injection pattern -- that I've been using since the late 90s, in half a dozen different languages. It's more explicit than some folks might like, but it's rock-solid, easy to use, and promotes good code behavior. Core concepts are: -- There is an overall Ecology, which is basically a container of "Ecots" (jargon for "member of the Ecology"). -- Each Ecot is conceptually a self-contained bit of system-singleton logic, in a class. -- Ecots may expose public traits (EcologyInterfaces) that they extend. These are typically pure interfaces, but cheating is allowed when convenient. -- No code is *ever* allowed to refer directly to an Ecot, only to an EcologyInterface. -- EcologyInterfaces are fetched from the Ecology, and are usually then cached, since they are stable throughout runtime. -- Ecots may declare initialization-time dependencies on specific EcologyInterfaces. It may seem slightly primitive, but this model (a) promotes good interface/implementation separation, and thus usually much better separation of concerns; (b) provides for a well-defined, reliable and non-cyclic initialization order without requiring anybody to have godly knowledge of dependencies; (c) allows for mutual dependencies while keeping compile times under control. It's easy to mock EcologyInterfaces for unit testing, and even to run parallel Ecologies for testing if needed. (Although that's rarely necessary these days.) I haven't talked it up much here, because it's a bit old-fashioned, but I've found myself dissatisfied with the alternatives for large-scale process structure. I'm currently using it in pretty complex environments on both the server/ScalaJVM+Play+Akka and client/ScalaJS sides; it just plain works well. The core code is here <https://github.com/jducoeur/Querki/blob/master/querki/scala/src/main/scala/querki/ecology/Ecology.scala>; one of these days, I should probably pull it out into a library... -- You received this message because you are subscribed to the Google Groups "scala-language" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.