设计模式-工厂模式(简单工厂,工厂模式,抽象工厂)

 

  1.工厂模式的初心,本质

工厂模式:本质是创建类的实例,将类的实例的创建和使用隔离。
模型特点:创建时根据参输的不同返回不同的实例。而这些个不同的类型的实例,都是同一个基类的实例。

简单工厂的特点:

       定义了一个类,这个类专门用于创建其他类的实例,这些被创建的类都有一个共同的父类。

工厂模式的特点:

        当这基类的子类因为业务分类为不同分组时,将简单工厂抽象出为接口,接口的不同实现中分别做对应的分组的实例创建。 特别的,这里工厂模式本质不变,只是对基类是实例的创建作了分组,不同分组各自做自己的 类的创建。

抽象工厂模式的特点:

        工厂模式中根据某个业务条件做了类的实例创建上的分组。但现在说除了 这个分组,还有个另一个维度的分组。这个时候实例的创建上就得考虑两个维度的事情。此时,要做的就是对外统一提供一个工厂类,用于实例的创建。对内将新的维度再次抽象出一个接口,用不同的实现类来做新维度的分类处理。

        即经验上来讲,用一般维度的划分不会太多,第二个维度,多会出现业务上的分族处理。

2.解决了什么问题

在于当你需要什么实例,只需要传入一个正确的参数,就可以获取你所需要的类的实例,而无须知道其创建细节。

3.工厂模式结构图

简单

 

模式分析:

​Factory:工厂角色。专门用于创建实例类的工厂,提供一个方法,该方法根据传递的参数不同返回不同类的具体实例。

​Product:抽象产品角色。为所有产品的父类。

​ConcreteProduct:具体的产品角色。

​简单工厂模式将对象的创建和对象本身业务处理分离了,可以降低系统的耦合度,使得两者修改起来都相对容易些。当以后实现改变时,只需要修改工厂类即可。

工厂模式:

Pizz:抽象产品:披萨。所有的披萨产品必须实现这个共同的接口,这样一来,使用这些产品的类既可以引用这个接口。而不是具体类。

NYStyleCheesePizza:具体一种披萨。

ChiagoStyleCh eesePizza:具体一种披萨。

PizaStore:抽象工厂。它实现了所有操纵产品的方法,但不实现工厂方法,即披萨类实例创建的方法。具体披萨实例创建的方法都在实现类中去做。这样就做到了分组。

NYPizzaStore、ChicagoPizzaStore:具体工厂。制造产品的实际工厂。各自负责创建各自分组的披萨实例。

抽象工厂模式:

模式结构说明。

AbstractFactory:抽象工厂。抽象工厂定义了一个接口,所有的具体工厂都必须实现此接口,这个接口包含了一组方法用来生产产品。

ConcreteFactory:具体工厂。具体工厂是用于生产不同产品族。要创建一个产品,客户只需要使用其中一个工厂完全不需要实例化任何产品对象。

AbstractProduct:抽象产品。这是一个产品家族,每一个具体工厂都能够生产一整组产品。

Product:具体产品。

本质上还是一个系统的产品比如说披萨,由两个维度作了分类。比如一个是产品口味,一个是产品原料地。

这个思想可以迁移到产品个族中,比如格力,可以生产冰箱族,可以生产空调族,冰箱族中又有不同品牌的冰箱,空调族中又有不同型号的空调。

 4.实战

4.1、简单工厂模式实战

​模式场景:

在一个披萨店中,要根据不同客户的口味,生产不同的披萨,如素食披萨、希腊披萨等披萨。

package com.example.demo.factory.simpleFactory.module;

/**
 * 抽象披萨类
 */
public abstract class Pizza {


    public abstract void prepare();

    public abstract void bake();

    public abstract void cut();

    public abstract void box();
}
package com.example.demo.factory.simpleFactory.module;

/**
 *具体的某种披萨
 */
public class CheesePizza extends Pizza {

    @Override
    public void bake() {
        System.out.println("bake CheesePizza ...");
    }


    @Override
    public void box() {
        System.out.println("box CheesePizza ...");
    }

    @Override
    public void cut() {
        System.out.println("cut CheesePizza ...");
    }

    @Override
    public void prepare() {
        System.out.println("prepare CheesePizza ...");
    }

}
package com.example.demo.factory.simpleFactory;

import com.example.demo.factory.simpleFactory.module.CheesePizza;
import com.example.demo.factory.simpleFactory.module.Pizza;

/**
 * 披萨工厂类,用于创建不同类型口味的披萨
 */

public class SimplePizzaFactory {
    public Pizza createPizza(String type) {
        Pizza pizza = null;

        if (type.equals("cheese")) {
            pizza = new CheesePizza();
            System.out.println("cheese pizza make successful");
        }
//        else if (type.equals("clam")) {
//            pizza = new ClamPizza();
//        } else if (type.equals("pepperoni")) {
//            pizza = new PepperoniPizza();
//        } else if (type.equals("veggie")) {
//            pizza = new VeggiePizze();
//
//        }

        return pizza;
    }
}
package com.example.demo.factory.simpleFactory;

import com.example.demo.factory.simpleFactory.module.Pizza;

/**
 * 披萨商场需要往外卖披萨,在披萨生产(实例创建时只需要调用披萨生产工厂就行,至于烘烤,切块,装盒等等其他工功能属性走其他流程)
 */
public class PizzaStore {
    //SimplePizzaFactory的引用
    SimplePizzaFactory factory;

    public PizzaStore(SimplePizzaFactory factory) {
        this.factory = factory;
    }

    public Pizza orderPizza(String type) {
        // //使用工厂对象的创建方法,而不是直接new。这里不再使用具体实例化
        Pizza pizza;
        pizza = factory.createPizza(type);

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

        return pizza;
    }

    public static void main(String[] args) {
        new PizzaStore(new SimplePizzaFactory()).orderPizza("cheese");
    }
}

 4.2、工厂模式实战

模式场景:

通过披萨的实例介绍了简单工厂模式。在披萨实例中,如果我想根据地域的不同生产出不同口味的披萨,如纽约口味披萨,芝加哥口味披萨。如果利用简单工厂模式,我们需要两个不同的工厂,NYPizzaFactory、ChicagoPizzaFactory。在该地域中有很多的披萨店,他们并不想依照总店的制作流程来生成披萨,而是希望采用他们自己的制作流程。本质上是披萨生产要分组了。此时披萨的生产用工厂模式。、

package com.example.demo.factory.factory;

import com.example.demo.factory.module.Pizza;

/**
 * 通过工厂模式创建披萨实例,其他业务问题交给其他逻辑处理,也可以封装在对应工厂类型地下去处理,就是一个入口通过入参驱动类型,往下是越来越复杂
 */
public abstract class PizzaStore {
    /*
     * 创建pizza的方法交给对应类别的子类去实现
     */
    abstract Pizza createPizza(String type);

    public Pizza orderPizza(String type) {
        Pizza pizza;
        pizza = createPizza(type);
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }


}


package com.example.demo.factory.factory;

import com.example.demo.factory.module.NYStyleCheesePizza;
import com.example.demo.factory.module.Pizza;

/**
 * 具体工厂。披萨分店。NYPizzaStore.java
 */
public class NYPizzaStoreFactory extends PizzaStore {
    @Override
    Pizza createPizza(String item) {
        Pizza pizza = null;
        if ("cheese".equals(item)) {
            pizza = new NYStyleCheesePizza();
        }
//        else if ("veggie".equals(item)) {
//            pizza = new NYStyleVeggiePizza();
//        } else if ("clam".equals(item)) {
//            pizza = new NYStyleClamPizza();
//        } else if ("pepperoni".equals(item)) {
//            pizza = new NYStylePepperoniPizza();
//        }

        return pizza;
    }
}

 

package com.example.demo.factory.factory;

import com.example.demo.factory.module.ChicagoStyleCheesePizza;
import com.example.demo.factory.module.Pizza;

public class ChicagoPizzaStoreFactory extends PizzaStore {
    @Override
    Pizza createPizza(String type) {
        Pizza pizza = null;
        if ("cheese".equals(type)) {
            pizza = new ChicagoStyleCheesePizza();
        }

//        else if ("clam".equals(type)) {
//            pizza = new ChicagoStyleClamPizza();
//        } else if ("pepperoni".equals(type)) {
//            pizza = new ChicagoStylePepperoniPizza();
//        } else if ("veggie".equals(type)) {
//            pizza = new ChicagoStyleVeggiePizza();
//        }
        return pizza;
    }
}

 

package com.example.demo.factory.module;

import java.util.ArrayList;
import java.util.List;

/**
 * 抽象产品类:Pizza.java
 */
public abstract class Pizza {

    protected String name;        //名称
    protected String dough;       //面团
    protected String sause;       //酱料
    protected List<String> toppings = new ArrayList<String>();       //佐料


    public void prepare() {
        System.out.println("Preparing " + name);
        System.out.println("Tossing dough");
        System.out.println("Adding sause");
        System.out.println("Adding toppings");
        for (int i = 0; i < toppings.size(); i++) {
            System.out.println("   " + toppings.get(i));
        }
    }

    public void bake() {
        System.out.println("Bake for 25 minutes at 350");
    }

    public void cut() {
        System.out.println("Cutting the pizza into diagonal slices");
    }

    public void box() {
        System.out.println("Place pizza in official PizzaStore box");
    }

    public String getName() {
        return name;
    }
}
package com.example.demo.factory.module;

/**
 * 具体产品类:NYStyleCheesePizza
 */
public class NYStyleCheesePizza extends Pizza {
    public NYStyleCheesePizza() {
        name = "Ny Style Sauce and Cheese Pizza";
        dough = "Thin Crust Dough";
        sause = "Marinara Sauce";

        toppings.add("Crated Reggiano Cheese");
    }
}

 

package com.example.demo.factory.module;

/**
 * 具体产品类:ChicagoStyleCheesePizza
 */
public class ChicagoStyleCheesePizza extends Pizza{
    public ChicagoStyleCheesePizza(){
                 name = "Chicago Style Deep Dish Cheese Pizza";
                dough = "Extra Thick Crust Dough";
                 sause = "Plum Tomato Sauce";

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

           public void cut(){
               System.out.println("Cutting the Pizza into square slices");
           }
}
package com.example.demo.factory;

import com.example.demo.factory.factory.ChicagoPizzaStoreFactory;
import com.example.demo.factory.factory.PizzaStore;

public class Test {
    public static void main(String[] args) {
        System.out.println("---------Joel 需要的芝加哥的深盘披萨---------");
        System.out.println("工厂模式创建实例");
        PizzaStore pizzaStore = new ChicagoPizzaStoreFactory();
        // 用户只需要选好工厂,给出具体的口味,其他的流水线作业交给底层去做, 用户不关注
        pizzaStore.orderPizza("cheese");
    }
}

 

4.3、抽象模式实战

​模式场景:

依然是披萨店。为了要保证每家加盟店都能够生产高质量的披萨,防止使用劣质的原料,我们打算建造一家生产原料的工厂,并将原料运送到各家加盟店。但是加盟店都位于不同的区域,比如纽约、芝加哥。纽约使用一组原料,芝加哥使用另一种原料。在这里我们可以这样理解,这些不同的区域组成了原料家族,每个区域实现了一个完整的原料家族。

首先创建一个原料工厂。该工厂为抽象工厂,负责创建所有的原料。

 public interface PizzaIngredientFactory {
 2     /*
 3      * 在接口中,每个原料都有一个对应的方法创建该原料
 4      */
 5     public Dough createDough();
 6
 7     public Sauce createSauce();
 8
 9     public Cheese createCheese();
10
11     public Veggies[] createVeggies();
12
13     public Pepperoni createPepperoni();
14
15     public Clams createClams();
16 }
原料工厂创建完成之后,需要创建具体的原料工厂。该具体工厂只需要继承PizzaIngredientFactory,然后实现里面的方法即可。

NYPizzaIngredientFactory.java
public class NYPizzaIngredientFactory implements PizzaIngredientFactory{
 2
 3     @Override
 4     public Cheese createCheese() {
 5         return new ReggianoCheese();
 6     }
 7
 8     @Override
 9     public Clams createClams() {
10         return new FreshClams();
11     }
12
13     @Override
14     public Dough createDough() {
15         return new ThinCrustDough();
16     }
17
18     @Override
19     public Pepperoni createPepperoni() {
20         return new SlicedPepperoni();
21     }
22
23     @Override
24     public Sauce createSauce() {
25         return new MarinaraSauce();
26     }
27
28     @Override
29     public Veggies[] createVeggies() {
30         Veggies veggies[] =  {new Garlic(),new Onion(),new Mushroom(),new RefPepper()};
31         return veggies;
32     }
33
34 }

 

 1 public abstract class Pizza {
 2     /*
 3      * 每个披萨都持有一组在准备时会用到的原料
 4      */
 5     String name;
 6     Dough dough;
 7     Sauce sauce;
 8     Veggies veggies[];
 9     Cheese cheese;
10     Pepperoni pepperoni;
11     Clams clams;
12
13     /*
14      * prepare()方法声明为抽象方法。在这个方法中,我们需要收集披萨所需要的原料,而这些原料都是来自原料工厂
15      */
16     abstract void prepare();
17
18     void bake(){
19         System.out.println("Bake for 25 munites at 350");
20     }
21
22     void cut(){
23         System.out.println("Cutting the pizza into diagonal slices");
24     }
25
26     void box(){
27         System.out.println("Place pizza in official PizzaStore box");
28     }
29
30     public String getName() {
31         return name;
32     }
33
34     public void setName(String name) {
35         this.name = name;
36     }
37
38 }

 

​
public class CheesePizza extends Pizza{
 2     PizzaIngredientFactory ingredientFactory;
 3
 4     /*
 5      * 要制作披萨必须要有制作披萨的原料,而这些原料是从原料工厂运来的
 6      */
 7     public CheesePizza(PizzaIngredientFactory ingredientFactory){
 8         this.ingredientFactory = ingredientFactory;
 9         prepare();
10     }
11
12     /
13      * 实现prepare方法
14      * prepare 方法一步一步地创建芝士比萨,每当需要原料时,就跟工厂要
15      */
16     void prepare() {
17         System.out.println("Prepareing " + name);
18         dough = ingredientFactory.createDough();
19         sauce = ingredientFactory.createSauce();
20         cheese = ingredientFactory.createCheese();
21     }
22
23 }

​
public abstract class PizzaStore {
 2     public Pizza orderPizza(String type){
 3         Pizza pizza;
 4         pizza = createPizza(type);
 5
 6         pizza.prepare();
 7         pizza.bake();
 8         pizza.cut();
 9         pizza.box();
10
11         return pizza;
12     }
13
14     /*
15     * 创建pizza的方法交给子类去实现
16      */
17     abstract Pizza createPizza(String type);
18 }
public class NYPizzaStore extends PizzaStore{
 2
 3     @Override
 4     Pizza createPizza(String type) {
 5         Pizza pizza = null;
 6         //使用纽约的原料工厂
 7         PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();
 8         if("cheese".equals(type)){
 9             pizza = new CheesePizza(ingredientFactory);
10             pizza.setName("New York Style Cheese Pizza");
11         }
12         else if("veggie".equals(type)){
13             pizza = new VeggiePizza(ingredientFactory);
14             pizza.setName("New York Style Veggie Pizza");
15         }
16         else if("clam".equals(type)){
17             pizza = new ClamPizza(ingredientFactory);
18             pizza.setName("New York Style Clam Pizza");
19         }
20         else if("pepperoni".equals(type)){
21             pizza = new PepperoniPizza(ingredientFactory);
22             pizza.setName("New York Style Pepperoni Pizza");
23         }
24         return pizza;
25     }
26 }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值