Main Design Principles

The main design principles that drive the implementation of PerfectJPattern are:

  • Modular composability: PerfectJPattern components are designed in a way that can be freely re-combined to produce new software elements covering new unforeseen use-cases. One of the keys to achieve this goal is creating components that minimally implement a given requirement; thus avoiding tangled, inflexible and non-reusable implementations. An illustration of this concept is e.g. the Componentized Adapter whose minimal implementation barely translates the generic AbstractSurrogate superclass terms to the standard Adapter terms found in the literature e.g. getComponent() becomes getTarget(). Any attempts to fix a single criteria to map features from Adaptee to Target would not only result in a tangled Adapter implementation but would also seriously hinder its usability. The solution was to combine the Adapter with the Strategy Pattern to externalize the Adapting criteria functional concern, so that new unforeseen Adapting criteria can be plugged in with no need to modify or even subclass the componentized Adapter implementation.
  • Self Documentation: PerfectJPattern components are faithful to the description and intent of the original Pattern found in the scientific literature. This provides PerfectJPattern with free documentation. Similarly, building software systems on top of Design Pattern components automatically provides documentation for those systems.

Naming interfaces with the 'I' prefix

As part of PerfectJPattern coding conventions, interface names are prefixed with 'I' e.g. ISubject and this convention is enforced with Checkstyle. I still carry this legacy from my initiation with Visual C++, COM and ATL. There are also stronger reasons why I prefer this convention over Sun Java Standard:

  • Provides a clear separation of interfaces from classes e.g. finding interface types using IDE tools is much simpler when all interfaces are prefixed with 'I'.
  • Similarly analyzing dependency reports is much more helpful e.g. reviewing JDepend reports to ensure that interface types depend only or mostly on other interface types.
  • Leaves better choices for naming concrete class type implementations e.g. class Subject vs. SubjectImpl or the like. I personally dislike very much the 'Impl' suffix. I believe that I am not alone regarding this preference.

PerfectJPattern Components: Trusted?

As explained in the welcome page, PerfectJPattern is inspired by the original work of Prof. Dr. Bertrand Meyer on Trusted Components. Prof. Meyer's approach to the Trustability of components is by means of the semantically rich Eiffel's Design by Contract where every class carries its correctness specification by means of design contracts: invariants, pre- and post-conditions.

PerfectJPattern's approximation to Trustability in Java is a combination of:

  • Defensive programming providing strong provider-client contracts in interface API method signatures enforced permanently. See the Design Notes next point below 'Defensive Programming'.
  • Test-driven development: every release of PerfectJPattern enforces compliance with the correctness specification with comprehensive Test Suites for every pattern component.
  • High quality build process: enforces coding rules, automates bug detection, and provides every bit of automated quality analysis reports available. Future enhancements include Java OO Metrics once it is available a "Chidamber and Kemerer Java Metrics" plugin for Maven.

Not only the provided components are carefully designed and tested but taken to the highest quality build cycle.

Defensive Programming approach

Currently PerfectJPattern embraces the Defensive Programming approach basically creating a filtering layer in its API where client-side programming errors that violate PerfectJPattern's pre-conditions will permanently result (both in testing and release stages) into unchecked runtime exceptions declared as part of the API.

I did some research e.g. Eiffel and Java mailing lists and newsgroups and found out that the general consensus is:

  • Eiffel community in general embraces more Design by Contract and overall discards Defensive Programming that yields negative impact on performance.
  • Sun and the Java community in general embraces more the Defensive Programming approach and this is reflected in the Sun's JDK implementation.
There is a note in Sun Java online guides regarding the use of the assert Java feature encouraging asserts to be used as a means of checking class invariants and post-conditions rather than pre-condition checking see Programming with Assertions: Putting Assertions Into Your Code. According to this it is discouraged the use of assertions in public methods but to use instead IllegalArgumentException

Since PerfectJPattern targets the Java community it was therefore initially adopted the Defensive Programming approach. This could change in the future though and move to the use of assertions. It depends mostly on the feedback from the community.

In my personal view though, there is no precondition violation in PerfectJPattern that should be signaled using Exceptions (either checked or unchecked) and my reasoning is that any precondition violation occurring in the PerfectJPattern API layer is a client programming error rather than an end-user input mistake. Programming errors are to be discovered during testing and debugging cycles and not in production, therefore in my opinion assertions would be the correct tool.

Logging support with SLF4J

Logging in PerfectJPattern is implemented on top of Simple Logging Facade for Java (SLF4J)

the main reasons for this are:

  • Flexibility to plug any concrete Logging implementation of choice e.g. Log4J
  • Logger is an interface! e.g. this provides a great platform to test code behavior based on logging output.
  • The concrete Logging implementation is statically hardwired at compile time thus SLF4J does not suffer from the class loader problems observed when using JCL.

Strict control on dependencies

I usually tend to stay away from libraries or any reusable piece of code with big dependency footprint. Therefore in PerfectJPattern it is minimized the dependency on third-party libraries e.g. the only third-party modules strictly required for reusing the core module are Apache Commons Lang and SLF4J. The Apache Commons Lang was imported because of its excellent utilities and its syntactic sugar e.g. Validate utility class.