Showing posts with label DCI. Show all posts
Showing posts with label DCI. Show all posts

Wednesday, May 23, 2018

DCI Implementation in Java

In DCI the class definition "shouldn't contain a single method that is specific to an application’s use case;" i.e. "the domain object is not cluttered by peripheral stuff that it would not contain if not for some use case."
https://dzone.com/articles/dci-architecture-is-visionary

It's suggested that a language that supports DCI should be able to inject behaviors at run-time, which Java can't do as of yet (unless we count Java 8 interface default methods?).

Roles are applied in a run-time context where the roles connect the objects. The reason being is that if the objects (by their static definition i.e. their "class") contain static associations to each and every possible other object it could interact with at run-time, it would quickly proliferate the number of statically defined associations necessary -- hence the rule of thumb to forbid use-case specific behavior within a class.

As for Java, I believe a good trade-off is to either A) admit that the project's software does not pertain to the "domain" at all but that all the objects defined are understood to be within the scope of the project's set of use-cases in that way it's ok to add use-case-specific behavior in the class definition; or B) keep the object's dumb as prescribed by DCI and then let the role's be statically defined and allow the number of the role "classes" to proliferate as needed to accommodate all the use-cases (algorithms plus associations to objects defined in the roles.) (In the latter case, a role is analogous to join table in SQL.)

Regarding option B: obviously DCI assumes domain objects pertain to the larger "domain" of the business and should stay more-or-less static, each maintaining its separate set of invariants. Therefore it might make sense to have use-case specific packages where all the use-case or project specific behaviors and associations among the domain objects are defined in a set of roles residing in their own project/use-case package, which serves as the context in DCI. You could even have a separate Spring XML config file containing all the associations between the use-case-specific classes and the domain objects -- injections go from the latter to the former but not the reverse unless via non-use-case-specific interfaces -- for this reason you would not be able to use @Autowired...@Qualifier because using annotations this way couples the class file definition itself to the use-case-specific algorithm and runs the risk of that proliferation of use-case-specific code in the domain class definition.

I actually lean toward A. My rationale is that the notion of a "domain" sounds nice in theory but in practice it's hard to scope and define because "domains" often overlap -- even if you consider the domain to be the entire enterprise, it may overlap with other enterprises at any given juncture due to mergers or joint ventures. My preference is to actually create project or epic specific models that reside in say a "model" package. These models can be transcripted via tools like ModelMapper or Dozer. Once the project has access to its own possibly trimmed-down model it might make sense to add use-case specific behavior to the model classes since the number of use-cases within a project/epic are likely to be limited in number, so the risk of object-to-object static coupling is minimized. That said, even here I prefer to use "role objects" that contain the algorithms and associations, so you still get DCI in a sense but without worrying about maintaining that nebulous domain concept.

Sunday, January 22, 2017

Algorithms and OOP

In addition to DCI, "generic programming" as well as the move to functional programming appears to add nuance to the OOP notion of joining behavior with data, at the least at the static class definition level. In other words, the notion of OOP I think is becoming more of a runtime notion rather than static notion where the object's definition is enhanced at runtime with injected behaviors, rather than having those behaviors baked into the object's class definition.
The Iterator abstraction is fundamental to an emerging technology called "generic programming". This strategy seeks to explicitly separate the notion of "algorithm" from that of "data structure". The motivation is to: promote component-based development, boost productivity, and reduce configuration management.
https://sourcemaking.com/design_patterns/iterator

Wednesday, May 30, 2012

DDD vs. DCI

With DDD you end up with either "Use-case-specific logic scattered across domain model creating logical dependency to use-cases. Unstable (frequently changing) domain model." or services with "zillions of calls to property setters and getters, low level of code re-use, entity logic scattered across services, tight coupling to domain layer"

With DCI "Use-case-bound domain behavior injected into domain object by the app"
http://www.slideshare.net/johaneltes/dci-with-groovy

Sunday, May 27, 2012

DCI - My Take

DCI tries to solve the problem of how to model transactions. It introduces notions such as Roles and Contexts which your domain objects adopt and interact within respectively. The problem is deciding now what to name your domain objects and to which to assign said roles? I pretty much disagree for instance that an account should be responsible for transferring money to another account; this is simply too anthropomorphic. If accounts are and should be dumb objects then why are they conferred the knowledge of how to perform money transfers?


I still like the idea of having broker objects like servant or avatar who in the user's mental model perform the act of taking money from one dumb account and placing it into another. Why should the account be smart? or possibly a "clerk" object who depending on the context plays the role of account closer, password resetter, withdrawer, depositor, issue escalater, etc.

Traits vs. Interfaces

Orthogonal concepts really. Interfaces are contracts, while traits code-reuse vehicles. I believe they are analogous to extension methods in C# and roles in DCI -- and possibly the delegate design pattern. In architectural terms they are complementary:

"creating traits that fulfill the capabilities required by an interface is the ideal use case  - rdlowrey http://stackoverflow.com/questions/9205083/php-traits-vs-interfaces