This document discusses various software design patterns including Singleton, Factory Method, Abstract Factory, Prototype, Facade, Data Access Object, and Model-View-Controller. It uses examples related to pizza orders and home theater systems to explain how each pattern addresses common software development problems by providing reusable solutions. Design patterns aim to increase code reuse, separation of concerns, and addressing changing requirements in a flexible manner. The document emphasizes that patterns help manage object instantiation and separation of concerns between the user interface, business logic and data layers of an application.
21. INTENT
ENSURE THAT A CLASS HAS ONLY
ONE INSTANCE, AND PROVIDE A
GLOBAL POINT OF ACCESS TO IT.
22. WHEN TO USE
1. ONLY ONE INSTANCE OF CLASS IS REQUIRED
2. MUST BE A SINGLE ACCESS POINT
3. NEED TO MANAGE OBJECT INSTANCES
23. 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
25. THE PROBLEMS OF BEING GLOBAL
NAMESPACE POLLUTION
NO ACCESS CONTROL
UNCERTAIN INITIALIZATION ORDER
26. CLASS DIAGRAM
Singleton
public static getInstance()
public String getData()
public singletonOperation()
private Singleton instance
private String singletonData
31. UNDERSTANDING THROUGH PIZZAS
Pizza orderPizza()
{
Pizza pizza = new Pizza();
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.pack();
return pizza;
}
one type of
pizza only??
32. 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?
33. 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;
}
34. 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();
}
}
}
36. CLASS DIAGRAM
Factory
public Product factoryMethod()
public void anOperation()
<<Product>>
ConcreteProduct
ConcreteFactory
public Product factoryMethod()
41. MAKING A PIZZA FROM SCRATCH
public abstract class Pizza
{
public Dough dough;
public Sauce sauce;
public Cheese cheese;
}
42. MAKING A PIZZA FROM SCRATCH
public class DominosCheesePizza extends Pizza
{
this.dough = new CheeseBurstDough();
this.sauce = new TomatoSauce();
this.cheese = new ParmesanCheese();
}
43. public class PizzaHutCheesePizza extends Pizza
{
this.dough = new ThinCrustDough();
this.sauce = new PlumTomatoSauce();
this.cheese = new MozarellaCheese();
}
MAKING A PIZZA FROM SCRATCH
44. 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();
}
46. HERE COMES THE FACTORY
public abstract class IngredientFactory
{
public Dough createDough();
public Sauce createSauce();
public Cheese createCheese();
}
47. 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();
}
}
48. 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();
}
}
49. public abstract class Pizza
{
Dough dough;
Sauce sauce;
Cheese cheese;
}
NO CHANGE TO OUR PIZZA
50. 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
51. PUTTING IT ALL TOGETHER
public Pizza createPizza (
IngredientFactory factory,
String type)
{
if (type.equals(Cheese)
return new CheesePizza(factory);
}
59. BACK TO PIZZAS!
public abstract class Pizza
{
Dough dough;
Sauce sauce;
Cheese cheese;
}
60. BACK TO PIZZAS!
public class BasicCheesePizza extends Pizza
{
public BasicCheesePizza (
IngredientFactory factory)
{
this.dough = factory.createDough();
this.sauce = factory.createSauce();
this.cheese = factory.createCheese();
}
}
61. BACK TO PIZZAS!
public class BasicGreekPizza extends Pizza
{
public BasicGreekPizza (
GreekIngredientFactory factory)
{
this.dough = factory.createDough();
this.sauce = factory.createSauce();
this.cheese = factory.createCheese();
}
}
62. 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);
}
}
63. A PIZZA REGISTRY
public class PizzaRegistry {
public static Pizza getPizza (string type)
{
Pizza pizza = basicPizzas.get(type);
return (Pizza) pizza.clone();
}
}
64. TIME TO ADD TOPPINGS
public class CheesePizza {
private Pizza pizza = null;
public buildPizza (Toppings[] toppings) {
pizza = PizzaRegistry.get(Cheese);
// add your toppings here
}
}
69. 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
70. 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!!
78. INTENT
PROVIDE IN THE APPLICATION A
SINGLE INTERFACE TO ACCESS THE
UNDERLYING PERSISTENCE
MECHANISM, LIKE A DATABASE.
79. DATA ACCESS CODE BOILERPLATE
REGISTER THE DRIVER
EXTRACT DATA FROM RESULTSET
EXECUTE A QUERY
OPEN A CONNECTION
CLEAN UP THE ENVIRONMENT
80. LET US ENCAPSULATE
class MySqlDataAccess {
public List<?> select (String query) {
// register driver
// open connection
// execute select query
// extract data
// clean up
}
}
81. LET US ENCAPSULATE
class MySqlDataAccess {
public Boolean insert (String query) {
// register driver
// open connection
// execute insert query
// extract data
// clean up
}
}
83. 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);
}
}
84. SINGLETON TO THE RESCUE
class MySqlDataAccess {
public List<?> select (String query) {
// register driver
// open connection
// execute select query
// extract data
// clean up
}
}
85. SINGLETON TO THE RESCUE
class MySqlDataAccess {
finalize() {
try {
conn.close();
} finally {
super.finalize();
}
}
}
93. PEOPLE ARE EVERYWHERE
class Person {
public String firstName;
public String lastName;
public String address;
public int age;
}
94. PEOPLE ARE EVERYWHERE
class PersonDAO {
private static DAL = new MySqlDal();
public Person getByFirstName (
String firstName) {
String query = SELECT * FROM people
WHERE firstName = +
firstName;
}
}
95. PEOPLE ARE EVERYWHERE
public Person getByFirstName (
String firstName) {
Map<?,?> result = DAL.select(query);
Person p = /* create from result */;
return p;
}