Adapter Factory and More Making the Concrete Abstract
Adapter, Factory, and More Making the Concrete Abstract 1
Factory Pattern: Motivation Correctly making objects is complex Especially making collection of related objects Parts of a car Look-and-feel of a window: canvas, scrollbar, etc. The correct making of objects is not easily centralized in one place Often do it all over code wherever object is needed Violates SRP and DRY DP angle is that “new” names and makes a concrete class; should be referring to abstract concrete class has to be named, but we can at least hide that from most of system encapsulating class will violate OCP, but no others will 2
Factory is the answer Actually a collection of patterns Simply factory (idiom) Factory Method Abstract Factory (not today) Concrete class; Mystery how to make one 3
2¢ Factory for Dating Events … static “Factory” methods keep Event details local 4
What’s wrong with 2¢ Factory? A. Doesn’t hide construction details adequately B. Should pass an enum argument rather than defining multiple methods: Event. make. Event(SEEMOVIE) C. Violates the Open/Closed principle D. “make” methods shouldn’t be static E. Name prefix should be “create”, not “make” 5
Simple Factory (idiom) How to make Events not necessarily part of Event 6
Comparison – increasingly abstract class My. Dating. Class { … Event event = new Event(2, “Order. Flowers”); // magic constants // concrete Event class (majorly violates OCP) Event event = Event. make. Order. Flowers(); // abstract class object (passed into constructor) Event event = factory. create. Event(FLOWERS); 7
Class Diagram for Simple Factory 8
What’s wrong with Simple Factory? A. create method has to know about all the concrete classes it new’s B. Client class composes concrete class C. Factory is a concrete class 9
Simple Factory is Good, but not OCP Simple. Event. Factory should implement Event. Factory interface Clients of SEF should then compose Event. Factory: class Date. Class { private Event. Factory factory; public Date. Class(Event. Factory factory) { this. factory = factory; } … Someone can implement a new class with Event. Factory interface, and Date. Class can use it with no modification Means that when Event. Factory is extended (new subclass), Date. Class is extended with new Event. Factory options. That’s open for extension! 10
Factory Method Style: Date as Factory ____Date____ create. Event() ____Youth____ create. Event() … ____Senior___ create. Event() Subclasses of Date are the factories! In this example, no parallel Date/Event class hierarchy Event hierarchy is “flat” – class hierarchy is implicit in data of Event What changes is time to first “flowers” event, what the flowers are, etc. 11
Factory Method Style: Separate Factory like SEF but in hierarchy with abstract super Super centralizes Event selector Subs implement making 12
Factory Motivation for Pizza Example: Franchising 13
Factory Method Class Diagram “composes” them all because their constructors are referenced 14
Object Relationships 15
Adapter Pattern Again? Composition and Delegation, again? 16
Adapter: Motivation Real-world examples: • Database connectors • Chat systems Adapter: • Uses Composition and Delegation • Adapter (wrapper) is not subclass of wrapped object (because we’re adapting) • Naming: Input. Stream. To. Reader. Adapter 17
Adapter: Example 18
Adapter: Class Diagram All the classic DP elements: Client is “open” because it composes interface Adapter implements interface, delegates to concrete class 19
Adapter: Exercise Java’s String. Tokenizer class breaks a string into words using a specific algorithm Oddly, it implements the Enumeration<E> interface instead of Iterator<E> interface Need to pass the String. Tokenizer to a class that requires (takes) an Iterator interface Enumeration<E> { boolean has. More. Elements(); E next. Element(); } interface Iterator<E> { boolean has. Next(); E next(); } Write an adapter from Enumeration to Iterator (Could do this for String. Tokenizer, but that’s less reusable!) 20
Adapter Exercise (solution) USE: Iterator<String> iter = new Enumeration. Iterator<String>(my. String. Tokenizer); while(iter. has. Next()) { String str = iter. next(); System. out. print(str + " "); } 21
- Slides: 21