Headline

Excessive illustration of design patterns in Java

Characteristics

Consider Contribution:javaVisitor and Contribution:javaTemplate for simpler implementations that also put to work some design patterns for illustrative purposes. The present implementation is somewhat extreme in that it aims to illustrate a larger number of design patterns possibly for the argument's sake, without strong practical incentive. So please be careful about consuming this implementation. Please also observe the name of this implementation, "...Exorcism", which is supposed to be a clear hint at the common danger of over-engineering a design. One way of going over the top is to prematurely weave an additional design pattern into a system without understanding the pros and cons of doing so, without actually establishing the proper incentive of deploying the pattern. To summarize, the present implementation stands out with its design density in terms of the number of patterns and pattern interactions as they are provoked, encountered, and addressed.

Illustration

Package org.softlang.company.model and subpackages hosts two object models for Feature:Hierarchical company. Package org.softlang.company.features.features hosts feature implementations. Package org.softlang.company.tests hosts JUnit tests; see below. Package org.softlang.company.features.util hosts library-like extensions (thereby extending java.util). All the remaining packages host pattern infrastructure and pattern instances.

Abstract Factory pattern

Package org.softlang.company.model defines the company object model in an interface-oriented manner. There are two alternative implementations of these interfaces. That is, package org.softlang.company.model.company.impl.pojo provide a simple, POJO-like implementation, whereas org.softlang.company.model.company.impl.bean implements objects with observability (in the sense of the Observable class of package java.util) and a parent axis. Client code can be parametric in the implementation on the grounds of factories of package org.softlang.company.model.company.factory. For instance, the code for constructing a sample company uses a factory parameter; see the Basics class of package org.softlang.company.tests. Some client code only works for one of the two implementations. For instance, the logging feature of package org.softlang.company.features.features relies on objects with observability specifically.

Adapter pattern

A class adapter is used when deriving the DepartmentImpl class of package org.softlang.company.model.company.impl.bean from the ContainerImpl class of the same package such that it implements the Department class of package org.softlang.company.model.company. An object adapter is used when down-grading the List interface of package java.util the interface SimpleList of package org.softlang.company.features.util such that much less methods are exposed for the rest of this projects. For instance, the class ObservableSimpleList of package org.softlang.company.features.util only implements the narrow interface.

Command pattern

The cut operation is implemented twice: once in package org.softlang.company.features.features and once in package org.softlang.company.features.command. The later implementation uses command objects to defer the execution of the cut operation. To this end, each employee is encapsulated in an command object of class CutEmployee and the batch of the derived command objects for employees is maintained by a command object of class CutCompany. All command objects provide execute and undo actions. In particular, command objects for individual employees back up the salary before they cut.

Composite pattern

A company is a composite structure that breaks down into departments, employees, and their properties. There is a rooting interface Component that provides the setter and getter for a name that is equally available on companies, departments, and employees. In the case of the package org.softlang.company.model.company.impl.bean, there are even additional shared methods because of the rooting class java.util.Observable. In this case, overriding is also leveraged so that addition and removal of observers is pushed into sub-components in the case of composite-like as opposed to leaf-like components.

Decorator pattern

The ObservableSimpleList class of package org.softlang.company.features.util effectively decorates a given (simple) list with observability (in the sense of the Observable class of package java.util). That is, an observable (simple) list combines the interfaces of (simple) lists and Observable. The ObservableSimpleList class wraps the underlying (simple) list and it also incorporates additional state because it derives from the Observable class which manages observers (listeners). Observable (simple) lists are used in the non-POJO implementation of the company object model. That is, the list of subunits for companies and departments is set up to be observable.

Observer pattern

There is clearly value in making company object structure observable (in the sense of the Observable class of package java.util). For instance, if we were providing a GUI, observability would help with implementing an MVC architecture. In this implementation, observability is leveraged for Feature:Logging and Feature:Ranking; see the corresponding classes of package org.softlang.features. Objects of the company object model are made observable in a way that gives credit to the part-whole structure. That is, registration of an observer with a company object is propagated down into all components. To this end, an observable (simple) list type is also used; see the ObserableSimpleList of package org.softlang.company.features.util.

Proxy pattern

Feature:Access control is implemented in a way that access to employee salaries is regulated. Proxy objects are used to to enforce the access control policy. By default, read and write access is enabled, but it can be configured even once the proxies have been deployed. All concrete classes of the object model for companies are proxied. That is, employees are proxied because their get/set salary members must be directly controlled, while departments and companies are proxied so that any added subunit will be transparently proxied. To summarize, company objects are initially and continuously enhanced to provide proxies for every component so that all salary access must go through access control.

Singleton pattern

We use functor objects for the sake of parameterizing traversal functionality in monoids; see classes Monoid and AddDoubles of package org.softlang.company.features.util. Those functor objects are good candidates for singletons; see the implementation of AddDoubles. There is a static member getInstance to retrieve the singleton, which is constructed upon request, if needed, or fetched from a static field otherwise. The use of a singleton helps here to emphasize the fact that no state is associated with monoids.

Template pattern

The cut operation can be understood as a "walk" over the company structure with a mutation to be applied to any employee encountered. Likewise, the total operation can be understood as a "reduction" or a "query" over the company structure where salaries are extracted from any employee encountered and those salaries are combined systematically. Package org.softlang.company.features.template captures the general notions of walkers and reducers as template methods. The primitive operations of these templates are to be defined by visit methods of an appropriate visitor. The template methods essentially compose the client visitors with traversal behavior. See the implementations of cut and total in package org.softlang.company.features.features.

Visitor pattern

Nearly all operations including those for totaling and cutting salaries are implemented as visitors; see package org.softlang.company.features.visitor for the visitor framework. There are two kinds of visitors: void visitors, i.e., visitors with void visit methods as well as returning visitors, i.e., visitors with visit methods with some uniform result type. The use of visitors is deeply integrated into the rest of this implementation. In particular, the template methods of package org.softlang.company.features.template also leverage visitors. Arguably, visitors are needed for the chosen object model because there is polymorphism propperly involved due to the abstract Subunit class with the concrete subclasses Employee and Department.

Issues

Additional patterns could be considered:

  • State pattern
  • Memento pattern
  • Strategy pattern
  • ...

Relationships

For basic OO without inheritance see Contribution:javaComposition.

For basic OO with inheritance see Contribution:javaInheritance.

For modular OO programming with static methods see Contribution:javaStatic.

For use of Java reflection see Contribution:javaReflection (data processing) and Contribution:javaSyb (SYB-style generic programming).

For design patterns see Contribution:javaTemplate (template design pattern), Contribution:javaVisitor (visitor design pattern) and Contribution:javaExorcism (excessive illustration of design patterns).

Architecture

The contribution follows a standardized structure:

  • inputs contains input files for tests
  • src/main/java contains the following packages:
    • org.softlang.company.features for implementations of Functional requirements.
      • org.softlang.company.features.command for command pattern.
      • org.softlang.company.features.features for variations of Namespace:Features.
      • org.softlang.company.features.template for template pattern.
      • org.softlang.company.features.util for library-like extensions.
      • org.softlang.company.features.visitor for visitor pattern.
    • org.softlang.company.model for implementations of Feature:Company.
      • org.softlang.company.model.company for abstract factory pattern.
        • org.softlang.company.model.company.factory for factories.
        • org.softlang.company.model.company.impl for implementations of companies, departments and employees.
          • org.softlang.company.model.company.impl.bean for objects with observability.
          • org.softlang.company.model.company.impl.pojo for POJOs.
      • org.softlang.company.model.proxy for proxy pattern.
  • src/test/java contains the following packages:

Usage

This contribution uses Technology:Gradle for building. Technology:Eclipse is supported.

See https://github.com/101companies/101simplejava/blob/master/README.md

Metadata


Ralf Lämmel edited this article at Wed, 26 Apr 2017 23:50:59 +0200
Compare revisions Compare revisions

User contributions

    This user never has never made submissions.

    User edits

    Syntax for editing wiki

    For you are available next options:

    will make text bold.

    will make text italic.

    will make text underlined.

    will make text striked.

    will allow you to paste code headline into the page.

    will allow you to link into the page.

    will allow you to paste code with syntax highlight into the page. You will need to define used programming language.

    will allow you to paste image into the page.

    is list with bullets.

    is list with numbers.

    will allow your to insert slideshare presentation into the page. You need to copy link to presentation and insert it as parameter in this tag.

    will allow your to insert youtube video into the page. You need to copy link to youtube page with video and insert it as parameter in this tag.

    will allow your to insert code snippets from @worker.

    Syntax for editing wiki

    For you are available next options:

    will make text bold.

    will make text italic.

    will make text underlined.

    will make text striked.

    will allow you to paste code headline into the page.

    will allow you to link into the page.

    will allow you to paste code with syntax highlight into the page. You will need to define used programming language.

    will allow you to paste image into the page.

    is list with bullets.

    is list with numbers.

    will allow your to insert slideshare presentation into the page. You need to copy link to presentation and insert it as parameter in this tag.

    will allow your to insert youtube video into the page. You need to copy link to youtube page with video and insert it as parameter in this tag.

    will allow your to insert code snippets from @worker.