Wednesday, July 4, 2018

CoR compared to Pipe and Filter

Java World implies the pipes-and-filters architectural style described by Parnas 
Software systems often employ the equivalent of pipes (e.g., email filters or a set of filters for a servlet). At the heart of pipes and filters lies a design pattern: Chain of Responsibility (CoR).

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."

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.

Sunday, August 30, 2015

Business Logic in OOP

It appears logic should not be mistaken with behavior when it comes to OOP, which embraces the coupling of state and behavior (that modifies that state). Logic belongs elsewhere, e.g. in a rules engine.

One of the "Advantages of [a] Rule Engine" is "Logic and Data Separation (breaking OO coupling of data and logic)" -

Which tables are affected is business logic as well. The database should not have any knowledge of which tables constitute a customer on the business level. These are better served in the business layer.

Thursday, August 27, 2015

Static State Shared from Libs Shared Among Webapps

One of the disadvantages of placing application libraries in the Tomcat lib folder is thread safety issues.

... if any of the classes has static state, you will find that the state is now shared across all webapps. This can cause the objects / types from one webapp to be seen by another, which can cause problems.

Stephen C

Tuesday, August 11, 2015

Advantage of Compiled vs Interpreted Languages

Same reason you'd choose GWT vs JavaScript:
One of the primary ways GWT speeds AJAX development is by allowing you to write your applications in the Java language. Because of this, you can take advantage of static type checking and time-tested patterns of object-oriented programming. These, when combined with modern IDE features like code completion and automated refactoring, make it easier than ever to write robust AJAX applications with well-organized code bases.

1) static type checking
2) code completion
3) automated refactoring

Thursday, March 26, 2015

How Agents Work

Wondering about exactly what agents are and what they are supposed to do. Finally found a simple example scenario which I believe is a compelling reason to use agents for when appropriate (in this case negotation):

Agents cooperate on a number of levels. First, they share their perception.
Next, we enabled our agents to share their agent state (e.g. that the
agent carries no gold items) and intentions (such as “I plan to pick gold at
X,Y”) as they may choose to go to the same unknown field or to pick the
same gold item. Now every agent can appraise from what it knows if it will
be better to leave the team member alone or to take the intention as its
own when its more promising.
Our approach to communication and cooperation is fully decentralised.
Each agent has the capability for finding the other agent on the network.
It then directly tells every agent about its perception, agent state and intentions.
There is neither a message broker nor a central instance which
coordinates the contest agents. Every agent builds its own world model from
what it is told by the server and the other agents. Every agent also plans for itself, taking the states and intentions of its teammates into account.