设计模式:工厂模式

首先工厂模式分为三种:简单工厂模式、工厂方法模式、抽象工厂模式。下面分别介绍这三种模式。

 注:在设计模式中,所谓的“实现一个接口”,并“不一定”表示写一个类,并利用implement来实现某个接口,而是泛指实现某个超类型(可以是接口或类)的某个方法。

一:简单工厂模式

  简单工厂模式其实不是一个设计模式,反而更想是一种编程习惯。将可变的和不可变的分离出来。

  简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个种类(这些种类继承自一个父类或接口)的实例。下面我们看下披萨工厂创建披萨给披萨店,代码如下:

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();
        }
        return pizza;
    }
}
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;
    }
}

  具体的披萨种类和披萨类后续会有代码,并且后续介绍另外两种模式时,会对有关代码进行一定修改。

二:工厂方法模式

  工厂方法模式定义一个用于创建对象的接口,让子类决定实例化哪个类。在简单工厂模式中,新增类型需要改动工厂类,而工厂方法模式使之前的体系无需修改,完全符合了开发-封闭原则。但工厂方法模式在客户端中还是需要进行逻辑判断,决定需要实例化哪一个工厂来实现实现类。例子代码如下:

  首先创建一个抽象的Pizza类

package com.learn.factory;
import java.util.ArrayList;

public abstract class Pizza {
    protected String name ;
    protected String dough;
    protected String sauce;
    protected ArrayList toppings = 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(int i = 0 ; i<toppings.size() ; i++){
            System.out.println(toppings.get(i));
        }
    }
    
    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;
    }
}

  然后创建具体的披萨类

public class ChicagoStyleCheesePizza extends Pizza{
    public ChicagoStyleCheesePizza(){
        name = "Chicago Style Deep Dish Cheese Pizza";
        dough = "Extra Thick Crust Dough";
        sauce = "Plum Tomato Sauce";
        toppings.add("Shredded Mozzarella Cheese");
    }
    
    public String getName(){
        return name;
    }
}
public class NYStyleCheesePizza extends Pizza{
    public NYStyleCheesePizza(){
        name = "NY Style Sauce and Cheese Pizza";
        dough = "Thin Crust Dough";
        sauce = "Marinara Sauce";
        toppings.add("Grated Reggiano Cheese");
    }
    
    public String getName(){
        return name;
    }
}
等等披萨种类

  接着创建抽象的披萨店类

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);
}

  然后创建具体的披萨店类

public class NYPizzaStore extends PizzaStore {

    @Override
    Pizza createPizza(String type) {
        if(type.equals("cheese")){
            return new NYStyleCheesePizza();
        }
        else if(type.equals("veggie")){
            return new NYStyleVeggiePizza();
        }
        return null;
    }
    
}

public class ChicagoStyleStroe extends PizzaStore{

    @Override
    Pizza createPizza(String type) {
        if(type.equals("cheese")){
            return new ChicagoStyleCheesePizza();
        }
        return null;
    }
    
}

  最后进行测试:

public class Test {
    public static void main(String[] args) {
        PizzaStore nyStore = new NYPizzaStore();
        PizzaStore chicagoStore = new ChicagoStyleStroe();
        
        Pizza pizza = nyStore.orderPizza("cheese");
        System.out.println("NY ordered a " + pizza.getName());
        System.out.println("----------");
        pizza =chicagoStore.orderPizza("cheese");
        System.out.println("Chicago ordered a " + pizza.getName());

    }
}

  运行结果:

     

 

三:抽象工厂模式

  抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要指明具体类。多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。 一个抽象工厂类,可以派生出多个具体工厂类。 每个具体工厂类可以创建多个具体产品类的实例。 

//抽象产品类1
public interface IProduct1 {
     public void show();  
}

//抽象产品类2
public interface IProduct2 {
     public void show();  
}

//具体产品类1
public class Product1 implements IProduct1 {  
    public void show() {  
        System.out.println("产品1");  
    }
}

//也是具体产品类1
public class Product1_1 implements IProduct1 {  
    public void show() {  
        System.out.println("也是产品1");  
    }
}


//具体产品类2
public class Product2 implements IProduct2 {  
    public void show() {  
        System.out.println("产品2");  
    }  
} 

//抽象工厂类
public interface IFactory {
    public IProduct1 createProduct1();  
    public IProduct2 createProduct2();  
}

//具体工厂类One
public class OneFactory implements IFactory{
    public IProduct1 createProduct1() {  
            return new Product1();  
    }  
    public IProduct2 createProduct2() {  
        return new Product2();  
    }  
}

//具体工厂类Two
public class TwoFactory implements IFactory{
    public IProduct1 createProduct1() {  
        return new Product1_1();  
    }  
    public IProduct2 createProduct2() {  
        return new Product2();  
    }  
}
//测试类
public class Test {
    public static void main(String[] args){  
        IFactory factory = new OneFactory();  
        factory.createProduct1().show();  
        factory.createProduct2().show();  
        
        factory = new TwoFactory();
        factory.createProduct1().show();
        factory.createProduct2().show();
    }  
}

运行结果:

产品1
产品2
也是产品1
产品2

 

四:总结:

  简单工厂模式:用来生产同一等级结构中的任意产品。

  工厂方法模式 :用来生产同一等级结构中的固定产品。

  抽象工厂模式 :用来生产不同产品族的全部产品。

 

  下一节:单例模式

转载于:https://www.cnblogs.com/Tony-Anne/p/6411888.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值