230 likes | 350 Views
Design Patterns. Def: Ways of capturing solutions to common occurring problems – typically specified in UML – assembled in libraries Look at selected GoF – sampling of Creational, Structural & Behavioural – structure, examples of usage, mutex/complementary
E N D
Design Patterns • Def: Ways of capturing solutions to common occurring problems – typically specified in UML – assembled in libraries • Look at selected GoF – sampling of Creational, Structural & Behavioural – structure, examples of usage, mutex/complementary • SQA - Promote consistency and with that reuse and maintainability, yadda… • Provides formulaic way of enhancing systems e.g. new domain data could mean, new controller/views+new factory+entity+new test cases, new strategy/algorithm to process, etc – standardizes approach to enhancements knock on effect: more accurate estimate tf, more timely delivery of releases…
Purpose & Merits • Common aim: create things! • Use AF when creating different flavours of related things e.g. Correspondence (CMF), Different widgets (GoF example) – first class citizen • Use FM when creating a particular type of thing – narrower view of the AF – sits inside class model – typically, AF’s are 1-N FMs • Merits: AF – Ideal for fwk/layering (decouples implementation, promotes abstraction/programming to interfaces/contract), Promotes Separation of responsibilities, Promotes reuse/consistency (as all good patterns should!), Common approach to implement concrete AF as Singletons (single level inheritance modelling) or pure static utility – no abstraction! • Merits: FM – Flexibility to customize specific types/behaviours, ideal for frameworks, Promotes reuses/consistency
Singleton - Structural Overview • Maintain a single instance of some class, e.g. Factory – typically, singletons since they don’t hold state-per-client • Traits: Private constructor, static getInstance() with DCL (Double Checked Lock) to guarantee integrity of initialisation of singleton reference (see Double Checked Locking: Clever but, brokenhttp://www.javaworld.com/javaworld/jw-02-2001/jw-0209-double.html)
Examples of Usage • Throughout Java Core libs 1.2,3,4,5.x, much OSS e.g. Log4J’s Logger. • Can introduce inheritance to provide flexibility in type of the object to maintain a reference to (I have never done this) • Best seen in factories; used in CMF to manage requests to a 3rd party service and tracking responses/failure+retry handling/replaying – singleton kept Map of requests with backing store used for replay in event of outage (to guarantee at-most-once processing), response handling/reconciliation through this single instance • Could implement a pool of references this way (with reference counting) – managing a list of instances over the degenerative singleton
Other Creational Patterns • Builder – creates something bit-by-bit – pluggable algorithms for creating X, Y, Z in piecemeal fashion • Prototype – Class capable of being cloned – primordial instance used to create others via cloning e.g. Object.clone() – alternative to AF when #of Cloneables is low, have little variation in state
Proxy – Structural Overview • Surrogate for another object e.g. remote proxy – hides transport/(un)marshalling e.g. RMI Service, Corba Service, Web Service – controls access to it
Examples of Usage • Often used for implementing security checking prior to performing some privileged operation perhaps via the SecurityManager and Java 2 Permissions model • Web services via JAXRPC can use proxies (stubs) (also DII or stub/proxy-less) – does things like Type registration, Qname mapping of types, Serializer registration, etc.. • RMI/EJB/Web Services, et.al. all generate stubs which in some way proxy the remote/target service endpoint (In RMI: Lease Management?) • CMF – base implementation of a proxy for an eService handling marshalling/transport of RPC across messaging boundary (Provider API or PAPI – silly name, never liked it!) • Other important uses: Testing – Unit testing: very useful java.lang.reflect.Proxy; Volume testing: detailed profiling troublesome sections of code with a auditing proxy, database profiling – pSpy – java.sql proxies for most of the java.sql package(!) profiling/auditing code – don’t forget: pluggable – use Factory to ‘hot swap’ proxy in and out of implementation (important in unit testing as well as in profiling/tuning)
Façade – Structure Overview • Provides a unified interface to a selection of subsystems or components
Examples Of Usage • Key goal is simplification – dealing with a single interface over many • Reduction in coupling which allows easier modification of both clients/service endpoints • Some examples in J2EE – use of a Session Bean (usually stateless) to capture some work or business flow with 1-N subsystems e.g. CRM, Payment Gateway, Middle-Office/Back Office components (which front other tiers/systems)
Adapter – Structural Overview • Allow two incompatible implementations to integrate through an common interface – e.g. Swing adapters like MouseAdapter – allow receipting of MouseEvents from the AWT Event System • C++ would prescribe multiple inheritance however, this is undesirable and impossible (for good reasons!) in Java hence, we prefer composition/delegation model (AdapterAdaptee) • Some other good examples of Adapter (Java Connector Architecture) – useful in connecting legacy systems… Web Services – wrapping existing components implemented in different language/platform/use different protocols • Differs from Façade in that it doesn’t define a new interface rather it reuses an existing interface • Typically used to cater for incompatibilities or (more likely) applied as an after-thought to facilitate coupling where not anticipated in initial design work
Examples of Usage • Swing event system related • CMF required an adapter to allow eComs to use Cybertrust 3rd party integration (via web service interface)
Other Structural Patterns • Bridge “Decouple an abstraction from the implementations so that the two can vary” (GoF) – abstracts ‘delegate’ to implementations – developing of complex fwks would best suit this pattern(?) • Composite – Tree structured node abstraction – nodes can be added/removed from composite but, not from leaf – both share same interface/abstraction but, leaf overrides to ignore. Can treat entire object graph as single object. Useful in processing XML into memory for editing (DOM model), SOAP msg has a nested structure suited to composite – treats all objects the same way (via the abstraction/interface) • Decorator – Changing ‘skin’ not the ‘guts’ – adding additional responsibilities to a class without subclassing/modifying class – delegation over inheritance (again) Isn’t this Proxy? No – adds behaviour not access control. • Flyweight – in two words: Pool implementation – manage lots of fine-grain objects with little intrinsic state, Thread pool, Connection pool, et.al.
Chain Of Responsibility – Structural Overview • Decouple requester/requestee with a variable chain of like-handlers and pass request to each allowing 0,1..N handlers process the request
Examples Of Usage • Merits: Reduces coupling between collaborating classes, Flexible – easy to add new handlers (when complemented with factory) to the chain, vary granularity of responsibilities across handlers for reuse • J2EE - Servlet filters are handlers, Axis implements CoR for a Web Service RPC • CMF – applies an ‘aggregate’ handler which assembles a chain of handlers to perform vetting on a correspondence. Each type of ICorrespondenceHandler is created via a CorrespondenceHandlerFactory. We didn’t implement AF around this though to allow for pluggable Handler chains based on Correspondence type
Template Method – Structural Overview • Define skeleton algorithm (template) with invariant steps in base class – defer specific implementation of one or more steps in the algorithm to subclasses (via abstract methods)
Examples of Usage • Merits: Fundamental pattern for code reuse • AKA – Inversion of Control (IoC), GoF ref as ‘Hollywood Principle’ • Ideal for implementations of fwk and container (Tomcat, JBoss, et.al.) – e.g. Entity Bean – container controls lifecycle of bean and informs of changes • CMF used TM for CoR handler implementation (cmd shell behaviour) e.g. TM’s for handling base cmd line assembly, etc. • Past projects used for implementing a base Action to distil behaviour like, single-signon (SSO), session management, VO mapping, failure handling/reporting (Exception=>ActionError) since struts base Action.execute() throws exceptions (I didn’t like the declarative nature of the exception handling and wanted more control over error reporting)
Visitor - Structural Overview • Process class hierarchy without modifying hierarchy e.g. validation BO state – implement in visitor and not in BO itself with other types of processing farmed out to different implementations of visitor
Examples Of Usage • Use when… want to add method for only some subclasses in hierarchy – instead, create new visitor to perform logic from the method via a ‘visitation’ on those subclasses that require the new processing • Merits: Collects like behaviour instead of scattergunning it across hierarchy, ‘Double dispatch’ – callback on the Visitor allows runtime binding to any supported class in hierarchy • CMF – used to assemble a command line for a shell cmd via processing a type of corro object into a set of arguments to a shell cmd to process e.g. iprint, iscan, isecure, future ‘i’ utilities • Sure many OSS projects have used them(!)
Other Behavioural Patterns • Memento – capture object state and reanimate at some later point (inherent facility in java: serialization) • Iterator – implemented in Java collections fwk • Observer – Listener/callback concept – rife in AWT/Swing and event-driven systems • Interpreter – never used this one(!) – define grammar which an ‘interpreter’ will process – narrow usage • Mediator – never implemented consciously(!) – perhaps when doing Swing/UI work in providing dynamic/context-sensitive feel to screens/dialogs e.g. highlight list selection => enable button as a consequence. • State – delegation/composition pattern to track state of something – like the visitor it can promote de-encapsulation. • Strategy – Your basic plugin approach – define interface – couple clients to it, vary the implementation – in java, reflection used to load implementations via property configured AF used over TM when varying all of an algorithm • Command – encapsulated logic in a request class – single hook to perform function of request which can vary in implementation – e.g. AWT/Swing Action – hook to button, menu, popup, Struts Action another example
Closing pattern… QnA • Power is in combining – template, strategy, command, etc.. Many are complementary (Factory-with-Template Method, etc..) • Take some advice from Martin Fowler (Is Design Dead?) when commenting on ‘Patterns and XP’: • Invest time in learning about patterns • Concentrate on when to apply the pattern (not too early) • Concentrate on how to implement the pattern in its simplest form first, then add complexity later. • If you put a pattern in, and later realize that it isn't pulling its weight - don't be afraid to take it out again.
Pattern References • Good references: GoF is seminal but, others for Java (Cooper textsx2) • hillside.net/patterns, pattenshare.org (MS site) • http://www.martinfowler.com/articles/injection.html#FormsOfDependencyInjection - Template Method elaborated… • http://martinfowler.com/bliki/PatternShare.html • http://today.java.net/pub/a/today/2004/12/23/patterns.html - • http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-double.html - DCL Broken article (Singleton) • Tool support: Enterprise Architect, Rose, Borland/Together, Holocentric, MagicDraw, Poseidon (ughh), yadda – pattern creation capability