際際滷

際際滷Share a Scribd company logo
the curious case of
DESIGN
PATTERNS
LETS TALK
BRIDGES
golden gate
bridge
PROPERTIES OF AN AWESOME BRIDGE
1. BE BIG
2. BE BEAUTIFUL
3. LET THOSE CARS PASS
4. FOLLOW THE DESIGN GUIDELINES
Design patterns
Design patterns
Design patterns
Design patterns
EACH
BRIDGE
IS
DIFFERENT
YET,
THEY ALL
ARE
SAME
NOTICE A
PATTERN?
All bridges in the world
can be categorized into
one of the four types.
or a combination of two
Engineering
is old.
It has matured over the years.
PYRAMIDS SKYSCRAPERS
THE FIRST
ROLLS ROYCE
WHEN BRIDGEMAKING
FAILS
WHEN SOFTWARE
FAILS?
interfaces
abstract classes
concrete classes
A design pattern is a general
reusable solution to a
commonly occurring problem
within a given context in
software design.
ERICH GAMMA
RICHARD HELM RALPH JOHNSON
JOHN VLISSIDES
the design pattern catalogue
singleton
factory method
prototype
abstract factory
builder
chain of
responsibility
command
interpreter
iteratormediator
memento
observer
state
strategy
template method
visitor
adapter
bridge
composite
decorator
韓温巽温糸艶
flyweight
proxy
singleton
INTENT
ENSURE THAT A CLASS HAS ONLY
ONE INSTANCE, AND PROVIDE A
GLOBAL POINT OF ACCESS TO IT.
WHEN TO USE
1. ONLY ONE INSTANCE OF CLASS IS REQUIRED
2. MUST BE A SINGLE ACCESS POINT
3. NEED TO MANAGE OBJECT INSTANCES
USE CASES
1. MULTIPLE OS WINDOWS : ONE WINDOW MANAGER
2. MULTIPLE PRINT JOBS : ONE PRINT SPOOLER
3. MULTIPLE FILES : ONE FILE MANAGER
4. ONE CONFIGURATION OBJECT ACROSS APPLICATION
How about
global variables?
THE PROBLEMS OF BEING GLOBAL
NAMESPACE POLLUTION
NO ACCESS CONTROL
UNCERTAIN INITIALIZATION ORDER
CLASS DIAGRAM
Singleton
public static getInstance()
public String getData()
public singletonOperation()
private Singleton instance
private String singletonData
<code/>
factory method
INTENT
DEFINE AN INTERFACE FOR
CREATING AN OBJECT, BUT LET
SUBCLASSES DECIDE WHICH CLASS
TO INSTANTIATE.
new
IS AN EVIL THING
UNDERSTANDING THROUGH PIZZAS
Pizza orderPizza()
{
Pizza pizza = new Pizza();
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.pack();
return pizza;
}
one type of
pizza only??
Pizza orderPizza()
{
Pizza pizza = new CheesePizza();
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.pack();
return pizza;
}
UNDERSTANDING THROUGH PIZZAS
what if you want
a pepperoni?
Pizza orderPizza (String type)
{
Pizza pizza;
if (type.equals(cheese))
pizza = new CheesePizza();
if (type.equals(pepperoni))
pizza = new PepperoniPizza();
if (type.equals(greek))
pizza = new GreekPizza();
UNDERSTANDING THROUGH PIZZAS
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.pack();
return pizza;
}
ENCAPSULATION GOODNESS
class PizzaFactory
{
public static Pizza create (String type)
{
switch (type)
{
case cheese: return new CheesePizza(); break;
case greek: return new GreekPizza(); break;
case pepperoni: return new PepperoniPizza();
}
}
}
SIMPLIFIED PIZZA ORDERS
Pizza orderPizza (String type)
{
Pizza pizza = PizzaFactory.create (type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.pack();
return pizza;
}
CLASS DIAGRAM
Factory
public Product factoryMethod()
public void anOperation()
<<Product>>
ConcreteProduct
ConcreteFactory
public Product factoryMethod()
public static void code
abstract factory
INTENT
PROVIDE AN INTERFACE FOR
CREATING FAMILIES OF RELATED
OBJECTS, WITHOUT SPECIFYING
THEIR CONCRETE CLASSES.
Depend upon abstractions.
Do not depend upon
concrete classes.
MAKING A PIZZA FROM SCRATCH
public abstract class Pizza
{
public Dough dough;
public Sauce sauce;
public Cheese cheese;
}
MAKING A PIZZA FROM SCRATCH
public class DominosCheesePizza extends Pizza
{
this.dough = new CheeseBurstDough();
this.sauce = new TomatoSauce();
this.cheese = new ParmesanCheese();
}
public class PizzaHutCheesePizza extends Pizza
{
this.dough = new ThinCrustDough();
this.sauce = new PlumTomatoSauce();
this.cheese = new MozarellaCheese();
}
MAKING A PIZZA FROM SCRATCH
ORDERING FROM MULTIPLE STORES
public Pizza createPizza (String store, String type)
{
if (store.equals(Dominos)
if (type.equals(Cheese)
return new DominosCheesePizza();
if (store.equals(PizzaHut)
if (type.equals(Cheese)
return new PizzaHutCheesePizza();
}
BUT THE ONLY
DIFFERENCE IS THE
INGREDIENTS!
HERE COMES THE FACTORY
public abstract class IngredientFactory
{
public Dough createDough();
public Sauce createSauce();
public Cheese createCheese();
}
HERE COMES THE FACTORY
public class DominosIngredientFactory
extends IngredientFactory {
public Dough createDough() {
return new CheeseBurstDough();
}
public Sauce createSauce() {
return new TomatoSauce();
} public Cheese createCheese() {
return new ParmesanCheese();
}
}
HERE COMES THE FACTORY
public class PizzaHutIngredientFactory
extends IngredientFactory {
public Dough createDough() {
return new ThinCrustDough();
}
public Sauce createSauce() {
return new PlumTomatoSauce();
} public Cheese createCheese() {
return new MozarellaCheese();
}
}
public abstract class Pizza
{
Dough dough;
Sauce sauce;
Cheese cheese;
}
NO CHANGE TO OUR PIZZA
public class CheesePizza extends Pizza
{
public CheesePizza (IngredientFactory factory)
{
this.dough = factory.createDough();
this.sauce = factory.createSauce();
this.cheese = factory.createCheese();
}
}
PUTTING IT ALL TOGETHER
PUTTING IT ALL TOGETHER
public Pizza createPizza (
IngredientFactory factory,
String type)
{
if (type.equals(Cheese)
return new CheesePizza(factory);
}
REMEMBER PIZZA FACTORY?
public Pizza createPizza (
IngredientFactory factory,
String type)
{
return PizzaFactory.create(type, factory);
}
boolean code = true;
prototype
INTENT
SPECIFY THE KINDS OF OBJECTS TO
CREATE USING A PROTOTYPICAL
INSTANCE, AND CREATE NEW OBJECTS
BY COPYING THIS PROTOTYPE.
OBJECT CREATION
CAN BE EXPENSIVE
database queries
data over a network
3rd party service
expensive calculations
database queries
data over a network
3rd party service
expensive calculations
BACK TO PIZZAS!
public abstract class Pizza
{
Dough dough;
Sauce sauce;
Cheese cheese;
}
BACK TO PIZZAS!
public class BasicCheesePizza extends Pizza
{
public BasicCheesePizza (
IngredientFactory factory)
{
this.dough = factory.createDough();
this.sauce = factory.createSauce();
this.cheese = factory.createCheese();
}
}
BACK TO PIZZAS!
public class BasicGreekPizza extends Pizza
{
public BasicGreekPizza (
GreekIngredientFactory factory)
{
this.dough = factory.createDough();
this.sauce = factory.createSauce();
this.cheese = factory.createCheese();
}
}
A PIZZA REGISTRY
public class PizzaRegistry {
private static Map<String, Pizza> basicPizzas;
static {
basicPizzas = new HashMap<String, Pizza>();
basicPizzas.add (Cheese,
new BasicCheesePizza(cheeseFactory);
basicPizzas.add (Greek,
new BasicGreekPizza(greekFactory);
}

}
A PIZZA REGISTRY
public class PizzaRegistry {

public static Pizza getPizza (string type)
{
Pizza pizza = basicPizzas.get(type);
return (Pizza) pizza.clone();
}
}
TIME TO ADD TOPPINGS
public class CheesePizza {
private Pizza pizza = null;
public buildPizza (Toppings[] toppings) {
pizza = PizzaRegistry.get(Cheese);
// add your toppings here
}
}
遺看稼壊看鉛艶.安姻庄岳艶(c看糸艶);
韓温巽温糸艶
INTENT
PROVIDE A UNIFIED INTERFACE TO A
SET OF INTERFACES IN A SUBSYSTEM,
IN ORDER TO MAKE THE SUBSYSTEM
EASIER TO USE.
HOME THEATRE COMPONENTS
TELEVISION
DVD PLAYER
FM TUNER
AMPLIFIER
SET TOP BOX
Video Out
Audio Out
SPEAKERS
WATCHING A MOVIE
TURN ON THE TV
SET AMLIPIFIER INPUT = DVD
TURN ON THE AMPLIFIER
TURN ON THE DVD PLAYER
SET TV TO WIDESCREEN MODE
SET AMLIPIFIER TO SURROUND SOUND
PLAY THE DVD
WATCHING A MOVIE, CONTD.
television.on()
amplifier.input = DVD;
amplifier.on()
dvdPlayer.on();
television.widescreen = true;
amplifier.soundMode = surround;
dvdPlayer.playDVD();
too many
commands for a
simple operation!!
How about
A SINGLE BUTTON
PLAY MOVIE
WHAT WE HAVE CURRENTLY
interface Television {  }
interface Amplifier {  }
interface Speakers {  }
interface SetTopBox {  }
interface FMTuner {  }
interface DVDPlayer {  }
FAADE TO THE RESCUE
class HomeTheatreFacade {
Television tv;
Amplifier amp;
DVDPlayer dvd;
FMTuner fm;
SetTopBox stb;
Speaker speaker;
}
class HomeTheatreFacade {

public HomeTheatreFacade (Television tv ) {
this.tv = tv;
this.amp = amp;
this.dvd = dvd;

}
}
FAADE TO THE RESCUE
class HomeTheatreFacade {

public void playMovie() {
tv.on();
tv.widescreen = true;
amp.on();
amp.input = dvd;
FAADE TO THE RESCUE
amp.soundMode = surround;
dvd.on();
dvd.playDVD();
}
}
Single Button!
System.out.print (code);
data access layer
INTENT
PROVIDE IN THE APPLICATION A
SINGLE INTERFACE TO ACCESS THE
UNDERLYING PERSISTENCE
MECHANISM, LIKE A DATABASE.
DATA ACCESS CODE BOILERPLATE
REGISTER THE DRIVER
EXTRACT DATA FROM RESULTSET
EXECUTE A QUERY
OPEN A CONNECTION
CLEAN UP THE ENVIRONMENT
LET US ENCAPSULATE
class MySqlDataAccess {
public List<?> select (String query) {
// register driver
// open connection
// execute select query
// extract data
// clean up
}
}
LET US ENCAPSULATE
class MySqlDataAccess {
public Boolean insert (String query) {
// register driver
// open connection
// execute insert query
// extract data
// clean up
}
}
EXPENSIVE OPERATIONS
REGISTER THE DRIVER
EXTRACT DATA FROM RESULTSET
EXECUTE A QUERY
OPEN A CONNECTION
CLEAN UP THE ENVIRONMENT
SINGLETON TO THE RESCUE
class MySqlDataAccess {
private static Connection conn = null;
static {
Class.forName(com.mysql.jdbc.Driver);
conn = DriverManager.getConnection(
db_url,username, password);
}

}
SINGLETON TO THE RESCUE
class MySqlDataAccess {

public List<?> select (String query) {
// register driver
// open connection
// execute select query
// extract data
// clean up
}
}
SINGLETON TO THE RESCUE
class MySqlDataAccess {

finalize() {
try {
conn.close();
} finally {
super.finalize();
}
}
}
data access object
INTENT
SEPARATE LOW-LEVEL DATA
ACCESSING API / OPERATIONS FROM
HIGH-LEVEL BUSINESS SERVICES, TO
MAKE THE UNDERLYING PERSISTENCE
MECHANISM AN ABSTRACTION.
never pass on data
always pass on objects
database is best kept a secret
WITH NO DAO
CLIENT DAL DATA
WITH NO DAO
CLIENT DAL DATA
UNSTRUCTURED
DATA PASSED
VENDOR
LOCK-INNO TYPE-SAFETY IN DATA
WITH DAO
CLIENT
DATA
OBJECT
DAL DATA
CHINESE WALL!
WITH DAO
CLIENT
DATA
OBJECT
DAL1 DATA1
DAL2 DATA2
PEOPLE ARE EVERYWHERE
class Person {
public String firstName;
public String lastName;
public String address;
public int age;
}
PEOPLE ARE EVERYWHERE
class PersonDAO {
private static DAL = new MySqlDal();
public Person getByFirstName (
String firstName) {
String query = SELECT * FROM people
WHERE firstName =  +
firstName;

}
}
PEOPLE ARE EVERYWHERE
public Person getByFirstName (
String firstName) {

Map<?,?> result = DAL.select(query);
Person p = /* create from result */;
return p;
}
YOU SHOULD USE A
DAL FACTORY
INSIDE THE DAO
PRINT code
model-view-
controller
INTENT
SEPARATE THE PRESENTATION LAYER,
THE BUSINESS LOGIC, AND THE DATA
MODEL OF A CLIENT-SERVER
APPLICATION.
HOW THE COMPONENTS INTERACT
model
CONTROLLERVIEW
HOW THE COMPONENTS INTERACT
FACEBOOK.COM
FACEBOOK SERVER
NEWSFEED
CONTROLLER
NEWSFEED DAO
MYSQL DAL
NEWSFEED VIEW
GENERATED HTML
HOW THE COMPONENTS INTERACT
FACEBOOK.COM
FACEBOOK SERVER
NEWSFEED
CONTROLLER
NEWSFEED DAO
MYSQL DAL
NEWSFEED VIEW
GENERATED HTML
MVC FRAMEWORKS
spring framework
asp.net mvc
codeigniter, cakephp
backbone, ember, angular
Design patterns

More Related Content

Design patterns