黑马程序员技术交流社区

标题: 【成都校区】设计模式之工厂模式 [打印本页]

作者: 逍遥来了    时间: 2019-1-3 08:52
标题: 【成都校区】设计模式之工厂模式
工厂模式有工厂方法模式和抽象工厂模式两类,分别举例说明:
1、工厂方法模式:定义了一个创建对象的接口,但由子类决定实例化的类是哪一个。即工厂方法让类把实例化推迟到子类。   

2、抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
设计原则  
依赖倒置原则:要依赖抽象,不要依赖具体类。  
    * 变量不可持有具体类的引用
    * 不要让类派生自具体类
    * 不要覆盖基类中已实现的方法


工厂方法模式示例  
定义一个披萨商店抽象类
```java
public abstract class PizzaStore {
    public Pizza orderPizza(String type) {
        Pizza pizza;

        pizza = createPizza(type);

        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();

        return pizza;
    }
    //抽象工厂方法,让子类创建披萨实例
    abstract Pizza createPizza(String type);
}
```  
具体商店实例一:
```java  
public class NYPizzaStore extends PizzaStore {
    @Override
    Pizza createPizza(String type) {
        if("cheese".equals(type)) {
            return new NYSytleCheesePizza();
        }else {
            return null;
        }
    }
}
```  
具体商店实例二:  
```java  
public class ChicagoStore extends PizzaStore {
    @Override
    Pizza createPizza(String type) {
        if("cheese".equals(type)) {
            return new ChicagoStyleCheesePizza();
        }else {
            return null;
        }
    }
}
```  
定义披萨抽象类  
```java  
public abstract class Pizza {
    String name;
    String dough;
    String sauce;
    ArrayList<String> topping = new ArrayList<>();

    void prepare() {
        System.out.println("Preparing:"+name);
        System.out.println("Tossing dough...");
        System.out.println("Adding sauce...");
        System.out.println("Adding toppings:");
        for (String s : topping) {
            System.out.println(" "+s);
        }
    }
    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");
    }
    public String getName() {
        return name;
    }
}
```  
创建两个披萨实例  
```java  
public class NYSytleCheesePizza extends Pizza {
    public NYSytleCheesePizza() {
        name = "NY style Sause and Cheese Pizza";
        dough = "Thin Crust Dough";
        sauce = "Marinara Sauce";

        topping.add("Grated Reggiano Cheese");
    }
}
```  
```java  
public class ChicagoStyleCheesePizza extends Pizza {
    public ChicagoStyleCheesePizza() {
        name = "Chicago Style Deep Dish Cheese Pizza";
        dough = "Extra Thick Crust Dough";
        sauce = "Plum Tomato Sauce";

        topping.add("Shredded Mozzarella Cheese");
    }

    @Override
    void cut() {
        System.out.println("Cutting the pizza into square slices");
    }
}
```  
创建测试类  
```java  
public class PizzaTestStore {
    public static void main(String[] args) {
        NYPizzaStore ny = new NYPizzaStore();
        ChicagoStore ch = new ChicagoStore();

        Pizza pizza = ny.orderPizza("cheese");
        System.out.println("order a "+pizza.getName());

        pizza = ch.orderPizza("cheese");
        System.out.println("order a "+pizza.getName());
    }
}
```  
抽象工厂模式示例
*可以利用反射来实现,优点是可以有任意多个子类创建,但需要知道类的全限定名,可以从Properties中读取。
```java
//测试主类,其余放在一个java文件中

public class FactoryReflectTest {
    public static void main(String[] args) {
        Animal a = AnimalFactory.getInstance("basic.test.Dog");
        if(a != null) {
            a.eat();
        }
    }
}
class AnimalFactory {
    Animal animal;
    public static Animal getInstance(String className) {
        Class<?> cls = null;
        Animal o = null;
        try {
            cls = Class.forName(className);
            o = (Animal) cls.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return o;
    }
}
interface Animal {
    void eat();
}
class Dog implements Animal {
    @Override
    public void eat() {
        System.out.println("吃肉");
    }
}
class Cat implements Animal {
    @Override
    public void eat() {
        System.out.println("吃鱼");
    }
}





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2