Pat’s Pizza creation Pizza orderPizza(String type){ Pizza pizza; if (type.equals(“cheese”)) { pizza = new CheesePizza(); } else if type.equals(“greek”))

Slides:



Advertisements
Similar presentations
Creational Design Patterns. Creational DP: Abstracts the instantiation process Helps make a system independent of how objects are created, composed, represented.
Advertisements

 Recent researches show that predicative programming can be used to specify OO concepts including classes, objects, interfaces, methods, single and multiple.
Factory Pattern Building Complex Objects. New is an implementation  Calling “new” is certainly coding to an implementation  In fact, it’s always related.
Chapter 4: The Factory Pattern. Consider the Following Code Fragment Duck duck; if (picnic) { duck = new MallardDuck(); } else if (hunting) { duck = new.
CS 210 Introduction to Design Patterns September 19 th, 2006.
Plab – Tirgul 12 Design Patterns
Informatics 122 Software Design II Lecture 5 Emily Navarro Duplication of course material for any commercial purpose without the explicit written permission.
Brittany Johnson CSCI360 Abstract Factory Design Pattern.
Patterns Lecture 2. Singleton Ensure a class only has one instance, and provide a global point of access to it.
IEG3080 Tutorial 7 Prepared by Ryan.
March Ron McFadyen1 Singleton pattern Singleton is designed to restrict instantiation of a class to one (or a few) objects. Useful when exactly.
ECE 355 Design Patterns Tutorial Part 2 (based on slides by Ali Razavi) Presented by Igor Ivković
PRESENTED BY SANGEETA MEHTA EECS810 UNIVERSITY OF KANSAS OCTOBER 2008 Design Patterns.
+ Informatics 122 Software Design II Lecture 8 Emily Navarro Duplication of course material for any commercial purpose without the explicit written permission.
Design Patterns.
CS 210 Introduction to Design Patterns September 28 th, 2006.
Design Pattern. The Observer Pattern The Observer Pattern defines a one-to-many dependency between objects so that when one object changes state, all.
Tech Talk Go4 Factory Patterns Presented By: Matt Wilson.
Patterns in programming 1. What are patterns? “A design pattern is a general, reusable solution to a commonly occurring problem in software. A design.
Software Components Creational Patterns.
Abstract Factory Abstract Factory using Factory Method.
Design Patterns CSCI 5801: Software Engineering. Design Patterns.
The Factory Patterns SE-2811 Dr. Mark L. Hornick 1.
Design Patterns Façade, Singleton, and Factory Methods Team Good Vibrations (1)
Decorator Explained. Intent Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to sub-classing for.
CS 210 Adapter Pattern October 19 th, Adapters in real life Page 236 – Head First Design Patterns.
Patterns in programming1. 2 What are patterns? Answers to common design problems. A language used by developers –To discuss answers to design problems.
Design Patterns CSIS 3701: Advanced Object Oriented Programming.
CS 210 Review Session October 5 th, Head First Design Patterns Chapter 4 Factory Pattern.
Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method.
Design Patterns. OO-Concepts Don’t rewrite code Encapsulation Inheritance Write flexible code.
Design Pattern. Definition: A design pattern is a general reusable solution to a commonly occurring problem within a given context in software design.
Software Design Patterns Curtsy: Fahad Hassan (TxLabs)
CS 415 N-Tier Application Development By Umair Ashraf June 22,2013 National University of Computer and Emerging Sciences Lecture # 3 Design Patterns (Observer,Factory,Singleton)
CS 210 Final Review November 28, CS 210 Adapter Pattern.
Design Patterns SE464 Derek Rayside images from NetObjectives.com & Wikipedia.
Java Design Patterns Java Design Patterns. What are design patterns? the best solution for a recurring problem a technique for making code more flexible.
Religious Studies 313 – Advanced Programming Topics.
The Factory Pattern Sanjay Yadav (ISE ).
Advanced Object-oriented Design Patterns Creational Design Patterns.
CSC 480 Software Engineering Design With Patterns.
CS 325: Software Engineering March 19, 2015 Applying Patterns (Part B) Code Smells The Decorator Pattern The Observer Pattern The Template Method Pattern.
Example to motivate discussion We have two lists (of menu items) one implemented using ArrayList and another using Arrays. How does one work with these.
Proxy Pattern defined The Proxy Pattern provides a surrogate or placeholder for another object to control access to it by creating a representative object.
Watching the movie the hard way…. Page 256 – Head First Design Patterns.
CS 210 Proxy Pattern Nov 16 th, RMI – A quick review A simple, easy to understand tutorial is located here:
Chapter 8 Object Design Reuse and Patterns. More Patterns Abstract Factory: Provide manufacturer independence Builder: Hide a complex creation process.
 Creational design patterns abstract the instantiation process.  make a system independent of how its objects are created, composed, and represented.
StarBuzz Coffee Recipe Boil some water Brew coffee in boiling water Pour coffee in cup Add sugar and milk Tea Recipe Boil some water Steep tea in boiling.
Five Minute Design Patterns Doug Marttila Forest and the Trees May 30, 2009 Template Factory Singleton Iterator Adapter Façade Observer Command Strategy.
An object's behavior depends on its current state. Operations have large, multipart conditional statements that depend on the object's state.
CS 350 – Software Design The Decorator Pattern – Chapter 17 In this chapter we expand our e-commerce case study and learn how to use the Decorator Pattern.
CLASSIFICATION OF DESIGN PATTERNS Hladchuk Maksym.
SE 461 Software Patterns. ABSTRACT FACTORY PATTERN.
SE 461 Software Patterns. FACTORY METHOD PATTERN.
CS 210 Introduction to Design Patterns September 14 th, 2006.
Design Patterns: MORE Examples
Object-Orientated Analysis, Design and Programming
Design Patterns Spring 2017.
How to be a Good Developer
Chapter 10 Design Patterns.
MPCS – Advanced java Programming
Factory Patterns 1.
Presented by Igor Ivković
Programming Design Patterns
Software Engineering Lecture 7 - Design Patterns
Object Oriented Design Patterns - Structural Patterns
ADAPTER FAÇADE FACTORY OBSERVER SINGLETON STRATEGY
Presented by Igor Ivković
CSC 480 Software Engineering
Presentation transcript:

Pat’s Pizza creation Pizza orderPizza(String type){ Pizza pizza; if (type.equals(“cheese”)) { pizza = new CheesePizza(); } else if type.equals(“greek”)) { pizza = new GreekPizza(); } else if type.equals(“pepperoni”)) { pizza = new PepperoniPizza(); } pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box() return pizza; }

Identifying the aspects that vary If the pizza shop decides to change the types of pizza it offers, the orderPizza method has to be changed.

Pizza orderPizza(String type){ Pizza pizza; if (type.equals(“cheese”)) { pizza = new CheesePizza(); } else if type.equals(“greek”)) { pizza = new GreekPizza(); } else if type.equals(“pepperoni”)) { pizza = new PepperoniPizza(); } pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box() } Part that varies. Part that remains constant

Encapsulating object creation if (type.equals(“cheese”)) { pizza = new CheesePizza(); } else if type.equals(“greek”)) { pizza = new GreekPizza(); } else if type.equals(“pepperoni”)) { pizza = new PepperoniPizza(); } SimplePizzaFactory

Building a simple pizza factory public class SimplePizzaFactory { public Pizza createPizza(String type) { Pizza pizza = null; if (type.equals("cheese")) { pizza = new CheesePizza(); } else if (type.equals("pepperoni")) { pizza = new PepperoniPizza(); } else if (type.equals("clam")) { pizza = new ClamPizza(); } else if (type.equals("veggie")) { pizza = new VeggiePizza(); } return pizza; }

Reworking the PizzaStore Class public class PizzaStore { SimplePizzaFactory factory; public PizzaStore(SimplePizzaFactory factory) { this.factory = factory; } public Pizza orderPizza(String type) { Pizza pizza; pizza = factory.createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; }

Complete example for Simple Factory SimplePizzaFactory factory = new SimplePizzaFactory(); PizzaStore store = new PizzaStore(factory); Pizza pizza = store.orderPizza("cheese");

Simple Factory Defined PizzaStore orderPizza() SimplePizzaFactory createPizza() Pizza prepare() bake() cut() box() CheesePizza VeggiePizza ClamPizza

Creating multiple factories PizzaStore NYPizzaFactory ChicagoPizzaFactory

Allowing the subclasses to decide SimplePizzaFactory createPizza() NYStylePizzaFactory createPizza() ChicagoStylePizzaFactory createPizza() A factory method handles object creation and encapsulates it in the subclass. This decouples the client code in the super class from the object creation that happens in the subclass.

class NYSimpleFactory extends SimpleFactory{ Pizza createPizza(String type){//creates Newyork specific Pizza pizza;... return pizza; } class PizzaStore { SimpleFactory factory; public PizzaStore(SimpleFactory fact){ factory = fact; } Pizza orderPizza(String type){ Pizza p = factory.createPizza(type); p.prepare(); p.bake(); p.cut(); p.box(); }

Creating multiple instances NYPizzaFactory nyFactory = new NYPizzaFactory(); PizzaStore nyStore = new PizzaStore(nyFactory); Pizza pizza = nyStore.orderPizza("cheese"); ChicagoPizzaFactory chicagoFactory = new ChicagoPizzaFactory(); PizzaStore chicagoStore = new PizzaStore(chicagoFactory); Pizza pizza = chicagoStore.orderPizza("cheese");

Simple Factory Pizza prepare() bake() cut() box() CheesePizza VeggiePizza PizzaStore Factory: SimplyPizzaFactory orderPizza() SimplePizzaFactory createPizza() NYStylePizzaFactory createPizza() ChicagoStylePizzaFactory createPizza()

Allowing the subclasses to decide PizzaStore createPizza() orderPizza() NYStylePizzaStore createPizza() ChicagoStylePizzaStore createPizza() A factory method handles object creation and encapsulates it in the subclass. This decouples the client code in the super class from the object creation that happens in the subclass.

Alternate approach – Abstract method – a framework for the pizza store public abstract class PizzaStore { abstract Pizza createPizza(String item); public Pizza orderPizza(String type) { Pizza pizza = createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; }

class NYPizzaStore extends PizzaStore{ Pizza createPizza(String type){..... return pizza; }

Creating multiple instances PizzaStore nyStore = new NYPizzaStore(); Pizza pizza = nyStore.orderPizza("cheese"); PizzaStore chicagoStore = new ChicagoPizzaStore(); Pizza pizza = chicagoStore.orderPizza("cheese");

Factory Method Pattern The factory method pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate. Factory method lets a class defer instantiation to subclass.

Factory Method Pattern UML

PizzaStore Factory Method Pattern PizzaStore createPizza() orderPizza() NYStylePizzaStore createPizza() ChicagoStylePizzaStore createPizza() Pizza Prepare() Bake() Cut() Box() NYStyleCheesePizza ChStyleCheesePizza Creator Classes Product Classes orderPizza(){ Pizz p=createPizza(); P.prepare(); p.bake(); p.cut(); p.box(); }

Looking at object dependencies Pizza Store NyStyle Cheeze Pizza NyStyle Cheeze Pizza NyStyle Cheeze Pizza NyStyle Clam Pizza Chicago Cheeze Pizza Chicago Cheeze Pizza Chicago Cheeze Pizza Chicago Clam Pizza

Design Principle Dependency Inversion Principle Depend upon abstractions. Do not depend upon concrete classes. “High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions.” [The Dependency Inversion Principle has been proposed by Robert C. Martin]

Applying the principle Pizza Store NyStyle Cheeze Pizza NyStyle Cheeze Pizza NyStyle Cheeze Pizza NyStyle Clam Pizza Chicago Cheeze Pizza Chicago Cheeze Pizza Chicago Cheeze Pizza Chicago Clam Pizza Pizza is an abstract class

Some guidelines to help with the principle Try and avoid having variables that refer to a concrete class Try and avoid deriving from a concrete class Try and avoid overriding an implemented method

Extending the factory pattern… Expanding the Pizza store example How do we deal with families of ingredients? Chicago: FrozenClams, PlumTomatoSauce, ThickCrustDough, MozzarellaCheese New York: FreshClams, MarinaroSauce, ThinCrustDough, ReggianoCheese California: Calamari, BruuuschettaSauce, VeryThinCrust, GoatCheese

Building the ingredient factories public interface PizzaIngredientFactory { public Dough createDough(); public Sauce createSauce(); public Cheese createCheese(); public Veggies[] createVeggies(); public Pepperoni createPepperoni(); public Clams createClam(); }

Building NY ingredient factory public class NYPizzaIngredientFactory implements PizzaIngredientFactory { public Dough createDough() { return new ThinCrustDough(); } public Sauce createSauce() { return new MarinaraSauce(); } public Cheese createCheese() { return new ReggianoCheese(); } public Veggies[] createVeggies() { Veggies veggies[] = { new Garlic(), new Onion(), new Mushroom(), new RedPepper() }; return veggies; } public Pepperoni createPepperoni() { return new SlicedPepperoni(); } public Clams createClam() { return new FreshClams(); }

Reworking the pizzas public abstract class Pizza { String name; Dough dough; Sauce sauce; Veggies veggies[]; Cheese cheese; Pepperoni pepperoni; Clams clam; abstract void prepare(); void bake() { System.out.println("Bake for 25 minutes at 350"); } void cut() { System.out.println("Cutting the pizza into diagonal slices"); } void box() { System.out.println("Place pizza in official PizzaStore box"); } void setName(String name) { this.name = name; } String getName() { return name; } public String toString() { \\ code to print pizza here }

Abstract Factory Pattern defined The abstract factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. Motivation Consider a composite class which must contain the same members but be created differently depending on the application. The idea behind abstract factory is that you can pass a class (the factory) to the constructor which has a standard interface. This interface is then used by the constructor, but the methods it uses are implemented differently for each kind of factory.

Abstract Factory Concrete Factory Abstract Product Concrete Product

ProductA1 Abstract Factory Pattern > AbstractFactory CreateProductA() CreateProductB() ConcreteFactory1 CreateProductA() CreateProductB() ConcreteFactory2 CreateProductA() CreateProductB() Client > AbstractProdcutA ProductA1 > AbstractProdcutB ConcreteFactory1 CreateProductA() CreateProductB() ProductB1 ProductA2 ProductB2

Real world scenarios Windows XP demonstrates the Abstract Factory pattern in its ability to instantiate families of Windows Forms elements.

Let’s say you are an online bookstore and people come to your website to buy books. When a customer orders a book, you just have another book distributor send the book directly to the customer. You are a middle man and you don’t stock the books. You have many distributors that you can choose to send the books directly to your customers. On-line book order

If the customer is in the east coast, you will use EastCoastDistributor If the customer is in the mid-west, you will use MidWestDistributor If the customer is in the west coast, you will use WestCoastDistributor

Client code: //the client gets the distributor without having //to know which distributor is being used IDistributor b = bookStore.GetDistributor();

Taking another step further, we can abstract out the BookStore as an interface and have more types of bookstores, as shown below:

IBookStore interface //the factory public interface IBookStore { IDistributor GetDistributor(); } //concrete factory public class BookStoreA : IBookStore { private CustomerLocation location; public BookStoreA(CustomerLocation location) { this.location = location; } IDistributor IBookStore.GetDistributor() { //internal logic on which distributor to return //*** logic can be changed without changing the client code **** switch (location) { case CustomerLocation.EastCoast: return new EastCoastDistributor(); case CustomerLocation.MidWest: return new MidWestDistributor(); case CustomerLocation.WestCoast: return new WestCoastDistributor(); } return null; }

IBookStore interface //the product public interface IDistributor { void ShipBook(); } //concrete product public class EastCoastDistributor : IDistributor { void IDistributor.ShipBook() { Console.WriteLine("Book shipped by East Coast Distributor"); } //concrete product public class MidWestDistributor : IDistributor { void IDistributor.ShipBook() { Console.WriteLine("Book shipped by Mid West Distributor"); } //conceret product public class WestCoastDistributor : IDistributor { void IDistributor.ShipBook() { Console.WriteLine("Book shipped by West Coast Distributor"); }

public enum CustomerLocation { EastCoast, MidWest, WestCoast } class Program { static void Main(string[] args) { Console.WriteLine("East Coast Customer:"); IBookStore bookstore = new BookStoreA(CustomerLocation.EastCoast); ShipBook(bookstore); Console.WriteLine("Mid West Customer:"); bookstore = new BookStoreA(CustomerLocation.MidWest); ShipBook(bookstore); Console.WriteLine("West Coast Customer:"); bookstore = new BookStoreA(CustomerLocation.WestCoast); ShipBook(bookstore); } private static void ShipBook(IBookStore store) { IDistributor d = store.GetDistributor(); d.ShipBook(); } Client code: Client code does not change.

/* * GUIFactory example */ abstract class GUIFactory { public static GUIFactory getFactory() { int sys = readFromConfigFile("OS_TYPE"); if (sys == 0) { return new WinFactory(); } else { return new OSXFactory(); } public abstract Button createButton(); } class WinFactory extends GUIFactory { public Button createButton() { return new WinButton(); }

class OSXFactory extends GUIFactory { public Button createButton() { return new OSXButton(); } abstract class Button { public abstract void paint(); } class WinButton extends Button { public void paint() { System.out.println("I'm a WinButton: "); } class OSXButton extends Button { public void paint() { System.out.println("I'm an OSXButton: "); }

public class Application { public static void main(String[] args) { GUIFactory factory = GUIFactory.getFactory(); Button button = factory.createButton(); button.paint(); } // Output is either: // "I'm a WinButton:" // or: // "I'm an OSXButton:" }

Suppose you are writing a program that performs remote diagnostics on computers made by a computer manufacturer called Stellar Microsystems. Over time, Stellar has produced computer models having substantially different architectures. Their oldest computers used CPU chips, MMU chips from Enginola. Since then, they have released three generations of computers based on their own ember CPU and MMU.

CPU // class CPU public abstract class CPU {... } // class EmberCPU class EmberCPU extends CPU {... } // class EnginolaCPU class EnginolaCPU extends CPU {... }

MMU // class MMU public abstract class MMU {... } // class EmberMMU class EmberMMU extends MMU {... } // class EnginolaMMU class EnginolaMMU extends MMU {... }

ArchitectureToolKit public abstract class ArchitectureToolkit { static final ArchitectureToolkit getFactory() { // algorithm to return concrete // architecture objects } // getFactory() public abstract CPU createCPU() ; public abstract MMU createMMU() ; } // AbstractFactory

class EmberToolkit extends ArchitectureToolkit { public CPU createCPU() { return new EmberCPU(); } // createCPU() public MMU createMMU() { return new EmberMMU(); } // createMMU() } // class EmberFactory

class EnginolatToolkit extends ArchitectureToolkit { public CPU createCPU() { return new EnginolatCPU(); } // createCPU() public MMU createMMU() { return new EnginolatMMU(); } // createMMU() } // class EnginolatFactory

public class Client { public void doIt () { AbstractFactory af; af = AbstractFactory.getFactory(); CPU cpu = af.createCPU(); } // doIt } // class Client

Game development example RTS (Real Time Strategy) games like Starcraft, Warcraft, Command and Conquer, etc. One of the common things that one is required to do is build structures that will allow one to build units from the structures.

A RTS game has two types of species. The Gaea Federation and the Borg. The game program allows three kinds of structures: Barracks, Headquarters and a WarRoom for the two species. Our abstract factory will create a family of units to be built from the structures for both species.

AbstractBarrack GaeaBarrackBorgBarrack AbstractHeadquarter GaeaHeadquarterBorgHeadquarter AbstractWarRoom GaeaWarRoomBorgWarRoom AbstractSpecies GetFactory() CreateBarrack() CreateHeadquarter() CreateWarRoom() GaeaFederation CreateBarrack() CreateHeadquarter() CreateWarRoom() Borg CreateBarrack() CreateHeadquarter() CreateWarRoom() CreateHeadquarter(){ new GaeaHeadquarter() } CreatWarRoom(){ new GaeaWarRoom() } CreateBarrack(){ new GaeaBarrack() }

AbstractSoupFactory defines the method names and return types to make various kinds of soup. The BostonConcreteSoupFactory and the HonoluluConcreteSoupFactory both extend the AbstractSoupFactory. Soup Factory Example

class SoupFactory { public SoupFactory() { } public ClamChowder makeClamChowder() { return new ClamChowder(); } public FishChowder makeFishChowder() { return new FishChowder(); }

class BostonSoupFactory extends SoupFactory { public ClamChowder makeClamChowder() { return new BostonClamChowder(); } public FishChowder makeFishChowder() { return new BostonFishChowder(); } } class HonoluluSoupFactory extends SoupFactory { public ClamChowder makeClamChowder() { return new HonoluluClamChowder(); } public FishChowder makeFishChowder() { return new HonoluluFishChowder(); }

abstract class Soup { string soupName; } class ClamChowder extends Soup { public ClamChowder() { soupName = "ClamChowder"; … } class FishChowder extends Soup { public FishChowder() { soupName = "FishChowder"; … }

class BostonClamChowder extends ClamChowder { public BostonClamChowder() { soupName = "QuahogChowder"; … } class BostonFishChowder extends FishChowder { public BostonFishChowder() { soupName = "ScrodFishChowder"; … } class BostonClamChowder extends ClamChowder { public BostonClamChowder() { soupName = "QuahogChowder"; … } class BostonFishChowder extends FishChowder { public BostonFishChowder() { soupName = "ScrodFishChowder"; … }

class HonoluluClamChowder extends ClamChowder { public HonoluluClamChowder() { soupName = "PacificClamChowder"; … } class HonoluluFishChowder extends FishChowder { public HonoluluFishChowder() { soupName = "OpakapakaFishChowder"; … }

Beer and Bar Example Basically there are bars and bars produce beer. You are not going to be able to order just a plain “Beer” from the bar. You want specific beers. Each bar is going to have its own beers.

So you have your beers. Now all you need are a few bars to serve them up to you! Now, it’s not just good programming practice to have that abstract bar there. If you want the house beer from BarC, you have to know that BarC is serving it. Remember that after a bar or two, you’d probably have no idea where you are? So enter the Abstract Bar Factory. You’ll just put a method that tells you where to drink.

public abstract class Bar { private static int BarCounter = 0; private static Bar[] itenerary = new Bar[4] { new BarA(), new BarB(), new BarC(), new BarD() }; public static Bar GetNextBar(){ if (BarCounter >= itenerary.Length) BarCounter = 0; return itenerary[BarCounter++]; } public Beer GetSamAdams() { return new SamAdams(); } public Beer GetMichUltra() { return new MichelobUltra(); } public abstract Beer GetHouseBeer(); }

public class BarA extend Bar { public Beer GetHouseBeer() { return new BarA_stout(); } public class BarB extend Bar { public Beer GetHouseBeer() { return new BarB_liteAmber(); } public class BarC extend Bar { public Beer GetHouseBeer() { return new BarC_Crap(); } public class BarD extend Bar { public Beer GetHouseBeer() { return new BarD_JagerBomb(); }

public abstract class Beer { public void Consume() { System.out.printf("Glug glug glug.... mmmmmm beer."); } public class BarA_stout extend Beer { public void Consume() { System.out.printf("Goes down smooth, nice frothy head. Goes great with a burger.....i want a burger!"); } public class BarB_liteAmber extend Beer { public void Consume() { System.out.printf("Great with wings, has a nice amber color and is an easy drink to have over conversation!"); } public class BarC_Crap extend Beer { public void Consume() { System.out.printf("Holy shit, this must be budwiser...we need to get the hell out of here, they probally spiked my Sam with water!"); } public class BarD_JagerBomb extend Beer { public void Consume() { System.out.printf("Wow....they lied, this ain't just beer..... One more round please!"); }

public class YouAndYourFriend { private Random beerTolorence = new Random(); public static void main(String args[]) { int trips = beerTolorence.nextInt(4, 20); //thats a lot of beer! for (int i = 0; i < trips; i++) { WeWantBeer(); } public void WeWantBeer() { Bar currentBar = Bar.GetNextBar(); //For the you currentBar.GetMichUltra().Consume(); //for your friend currentBar.GetSamAdams().Consume(); //for you both currentBar.GetHouseBeer().Consume(); }

Excellent, now, you and your friend just need to drink the beer. Note the simplicity here! You don’t care where you are drinking. If it’s on the itinerary, you are going to drink there! And best of all, you don’t need to keep track of where to go next or where we’ve been. Abstract Factories are great for getting drunk, just remember that and you’ll be OK.

Summary so far.. OO Basics Abstraction Encapsulation Inheritance Polymorphism OO Principles Encapsulate what varies Favor composition over inheritance Program to interfaces not to implementations Strive for loosely coupled designs between objects that interact Classes should be open for extension but closed for modification. Depend on abstracts. Do not depend on concrete classes. Only talk to your friends Hollywood principles: don’t call us, we will call you. Depend on abstracts. Do not depend on concrete classes.

Summary so far… OO Patterns Strategy Pattern defines a family of algorithms, Encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it. Observer Pattern defines a one-to-many dependency between objects so that when one object changes state, all of its dependents are notified and updated automatically. Decorator Pattern – attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative for sub-classing for extending functionality Singleton Pattern – ensure a class only has one instance, and provide a global point of access to it Adapter Pattern converts the interface of a class into another interface the clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces. Façade Pattern provides a unified interface to a set of interfaces in a subsystem. Façade defines a higher level interface that makes the subsystem easier to use. Template Pattern defines steps of an algorithm. Subclasses cannot change the algorithm (final). It facilitates code reuse. Factory Method – Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory method lets a class defer instantiation to the subclasses. Abstractor Factory – Provide an interface for creating families of related or dependent objects without specifying their concrete classes.