"If you don't know where you are going, you might wind up someplace else." - Yogi Berra
This document describes the Goals, Stategies and Code Conventions for CAS3 Design and Development. Design Goals are where we think we are going...without these nothing else would make much sense. Strategies provide guidelines and practical knowledge for achieving our goals. Code Conventions are simple but important code formatting rules that ensure our code base is consistent and readable. It is assumed that every CAS3 contributer is familiar with this document.
- First and foremost CAS3 will be Supple, Extensible and Elegant. It will be a joy to install, configure and run.
- CAS3 will maintain backward compatibility with the CAS 2.0 and CAS 1.0 protocols while providing extension points for well-known modifications and new features such as support for Web Services, SAML and Shibboleth.
- CAS Clients written for older versions of CAS will work with CAS3 without modification. Of course older clients may not be able to take advantage of new features unless they are updated.
something about DDD, UL, Spring, etc.
Interface names should correspond to the natural name of the concept being modeled. For instance, the proper name for an interface that represents a ticket is
Ticket. The name should be chosen carefully so that it evokes the responsibilities inherent in our common understanding of the domain. In otherwords, a "Rose is a rose is a rose is a rose." This approach is important. It ensures the code easy to read, understand and discuss. It reinforces the best practice of programming to interfaces and our use of Ubiquitous Language to craft a proper Domain Model.
Whereas interface names should evoke the specific concept being modeled, implementation names decorate the natural name with clues about the intended use or characteristic of the implementation.
Consider an interface named
Foobar. The various implementation names could be:
AbstractFoobar- skeletal implementation typically using the Template Method Pattern (requires subclassing)
SimpleFoobar- a simple version with more impls likely
DefaultFoobar- the default impl with more impls possible
FoobarImpl- the only possible impl (most likely final - prohibits subclassing)
FoobarSupport- a convenient concrete impl with Hook Methods (does not require sublassing, but possible)
This approach provides the reader a map of the design contours and extention points for adaptation and integration.
AbstractFoobar is an skeletal implementation that provides a base level of functionality. They typically use the Template Method Pattern and always require subclassing. Abstract implementations can be used to support all the other implementation types including Simple, Default, Internal and Support.
AbstractTicket is a good example of organizing common Ticket behavior with this approach.
SimpleFoobar is simply the simplest impl possible. More sophisticated alternatives are likely to be provided by CAS3 and by users. An example would be
SimpleTestUsernamePasswordAuthenticationHandler , a simple test implemenation of the
AuthenticationHandler interface. CAS3 provides a number of more sophisticated alternatives in the
org.jasig.cas.authentication.handler.support package that can be configured at runtime.
DefaultFoobar on the otherhand is the production quality default or common impl. Alternatives are possible and may be supplied by CAS3 or by users.
DefaultTicketFactory is an example which provide the out-of-the-box default or common implementation of the
TicketFactory interface. While alternatives are possible, the product will function properly in production using this implementation without any configuration done by the user.
FooBarImpl is an internal product component. It is not designed for customization and does not make up part of the public API. Typically only one implementation exists and it should be made as inaccessible as possible to the outside world by making it final, package visible, or even private static nested. [Bloch, 2001] (The private solution, however, makes is less convenient to unit test. Restricting to package scope is a good mix of encapsulation and exposure that still enables JUnit testing with the corresponding test being in the same package as the class to be tested.)
TicketManagerImpl is a good example of an internal product component implementation.
FoobarSupport is a convenient concrete impl that provides full functionality. Subclassing is not required, but made possible by design. Extensibility is typically supported with one or more Hook Methods.
Packages define logical subsystems
loose coupling between them
names part of Ubiquitous Language
If there is one implementation for any given interface, it belongs in the same package as the interface. However, when there are multiple implementations for an interface they go into a support sub-package. For example the
TicketCreator interface resides in
org.jasig.cas.ticket.factory package while multiple implementations namely
TicketGrantingTicketCreator reside in
See our Code Conventions guide.