Head First——工厂模式

文章介绍了三种创建型设计模式:简单工厂模式用于隔离对象创建和使用,但不符合开闭原则;工厂方法模式解决了简单工厂的扩展问题,遵循开闭原则;抽象工厂模式则能提供多个相关对象的创建,增强了灵活性,但增加了复杂性。
摘要由CSDN通过智能技术生成

阅读Head First的笔记

除了使用new操作符之外,还有更多制造对象的方法。你将了解到实例化这个活动不应该总是公开地进行,也会认识到初始化经常造成“耦合”问题。
工厂模式将从复杂的依赖中帮你脱困。

简单工厂模式:

简单工厂模式的核心是定义一个创建对象的接口,将对象的创建和本身的业务逻辑分离,降低系统的耦合度,使得两个修改起来相对容易些,当以后实现改变时,只需要修改工厂类即可。
在这里插入图片描述
在这里插入图片描述

但是压力来自于增加更多的比萨类型

在这里插入图片描述
现在最好将创建对象移至orderPizza之外,把创建比萨的代码移到另一个对象中,由这个新对象专职创建比萨。

我们称这个新对象为:“工厂”

工厂处理创建对象的细节,一旦有了工厂,orderPizza()就变成了此对象的客户。当需要比萨时,就叫比萨工厂做一个。
其实简单工厂不是一个设计模式,反而比较像是一种编程习惯。

public class Pizza {
    private String pizzaName;

    public String getPizzaName() {
        return pizzaName;
    }

    public void setPizzaName(String pizzaName) {
        this.pizzaName = pizzaName;
    }
}
/**
 * 简单Pizza工厂
 */
public class PizzaFactory {

    public static Pizza getPizza(String type){
        Pizza pizza = null;
        if(type.equals("cheese")){
            pizza = new CheesePizza();
        }else if(type.equals("greek")){
            pizza = new GreekPizza();
        }
        return pizza;
    }

}
public class PizzaStore {

    void prepare(String pizzaName){
        System.out.println("准备中 "+pizzaName);
        System.out.println("和面团中....");
        System.out.println("添加酱汁");
        System.out.println("添加配料:");
    }
    void bake(){
        System.out.println("准备烘烤 25 分钟...");
    }
    void cut(){
        System.out.println("烘烤完成,进行切割");
    }
    void box(){
        System.out.println("切割完毕,进行装盒");
    }

    public  Pizza orderPizza(String type){
        Pizza pizza = PizzaFactory.getPizza(type);
        assert pizza != null;
        prepare(pizza.getPizzaName());
        bake();
        cut();
        box();
        return pizza;
    }
}
public class GreekPizza extends Pizza{
    public GreekPizza(){
        this.setPizzaName("GreekPizza!!");
    }
}

public class CheesePizza extends Pizza{
    public CheesePizza(){
        this.setPizzaName("CheesePizza!!");
    }
}
/**
 * 简单工厂模式:
 * 将创建一类对象的细节封装在一个对象中,外界只需要通过这个对象(工厂对象)根据特定的参数直接获取想要的对象即可。
 */
public class MainTest {
    public static void main(String[] args) {
        Pizza pizza = new PizzaStore().orderPizza("cheese");
    }
}
简单工厂模式的优缺点:

简单工厂模式提供专门的工厂类用于创建对象,实现了对象创建和使用的职责分离,客户端不需知道所创建的具体产品类的类名以及创建过程,只需知道具体产品类所对应的参数即可,通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

但缺点在于不符合“开闭原则”,每次添加新产品就需要修改工厂类。在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展维护,并且工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。

为了解决简单工厂模式的问题,出现了工厂方法模式

工厂方法模式:

工厂方法模式将工厂抽象化,并定义一个创建对象的接口。每增加新产品,只需增加该产品以及对应的具体实现工厂类,由具体工厂类决定要实例化的产品是哪个,将对象的创建与实例化延迟到子类,这样工厂的设计就符合“开闭原则”了,扩展时不必去修改原来的代码。在使用时,用于只需知道产品对应的具体工厂,关注具体的创建过程,甚至不需要知道具体产品类的类名,当我们选择哪个具体工厂时,就已经决定了实际创建的产品是哪个了。

但缺点在于,每增加一个产品都需要增加一个具体产品类和实现工厂类,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。

  • 抽象工厂 AbstractFactory: 工厂方法模式的核心,是具体工厂角色必须实现的接口或者必须继承的父类,在 Java 中它由抽象类或者接口来实现。
  • 具体工厂 Factory:被应用程序调用以创建具体产品的对象,含有和具体业务逻辑有关的代码
    抽象产品 AbstractProduct:是具体产品继承的父类或实现的接口,在 Java 中一般有抽象类或者接口来实现。
  • 具体产品 Product:具体工厂角色所创建的对象就是此角色的实例。
public class CaliforniaPizzaFactory implements PizzaFactory{
    @Override
    public Pizza getPizza(String type) {
        Pizza pizza = null;
        if(type.equals("California1")){
            pizza = new CaliforniaPizza1();
        }
        return pizza;
    }
}
public class ChicagoPizzaFactory implements PizzaFactory {
    @Override
    public Pizza getPizza(String type) {
        Pizza pizza = null;
        if(type.equals("ChicagoPizza1")){
            pizza = new ChicagoPizza1();
        }
        return pizza;
    }

}
public class NYPizzaFactory implements PizzaFactory{
    @Override
    public Pizza getPizza(String type) {
        Pizza pizza = null;
        if(type.equals("NY1")){
            pizza = new NYPizza1();
        }else if(type.equals("NY2")){
            pizza = new NYPizza2();
        }
        return pizza;
    }
}
public interface PizzaFactory {
    Pizza getPizza(String type);
}
public class CaliforniaPizza1 extends Pizza{
    public CaliforniaPizza1(){
        this.setPizzaName("CaliforniaPizza1");
    }
}
public class ChicagoPizza1 extends Pizza{
    public ChicagoPizza1(){
        this.setPizzaName("ChicagoPizza1");
    }
}

public class NYPizza1 extends Pizza{
    public NYPizza1(){
        this.setPizzaName("NYPizza1");
    }
}
public class NYPizza2 extends Pizza{
    public NYPizza2(){
        this.setPizzaName("NYPizza2");
    }
}
public class Pizza {
    private String pizzaName;

    public String getPizzaName() {
        return pizzaName;
    }

    public void setPizzaName(String pizzaName) {
        this.pizzaName = pizzaName;
    }
}
public class PizzaStore {

    private PizzaFactory pizzaFactory;

    public PizzaStore(PizzaFactory pizzaFactory){
        this.pizzaFactory = pizzaFactory;
    }

    void prepare(String pizzaName){
        System.out.println("准备中 "+pizzaName);
        System.out.println("和面团中....");
        System.out.println("添加酱汁");
        System.out.println("添加配料:");
    }

    void bake(){
        System.out.println("准备烘烤 25 分钟...");
    }
    void cut(){
        System.out.println("烘烤完成,进行切割");
    }
    void box(){
        System.out.println("切割完毕,进行装盒");
    }

    public Pizza orderPizza(String type){
        Pizza pizza = pizzaFactory.getPizza(type);
        assert pizza != null;
        prepare(pizza.getPizzaName());
        bake();
        cut();
        box();
        return pizza;
    }
}
public class MainTest {
    public static void main(String[] args) {
        //纽约分店
        PizzaStore pizzaStore1 = new PizzaStore(new NYPizzaFactory());
        pizzaStore1.orderPizza("NY1");

        //芝加哥分店
        PizzaStore pizzaStore2 = new PizzaStore(new ChicagoPizzaFactory());
        pizzaStore2.orderPizza("ChicagoPizza1");

        //加州分店
        PizzaStore pizzaStore3 = new PizzaStore(new CaliforniaPizzaFactory());
        pizzaStore3.orderPizza("California1");
    }
}
抽象工厂模式:

在工厂方法模式中,我们使用一个工厂创建一个产品,一个具体工厂对应一个具体产品,但有时候我们需要一个工厂能够提供多个产品对象,而不是单一的对象,这个时候我们就需要使用抽象工厂模式。

public class CaliforniaPizza1 extends Pizza {
    public CaliforniaPizza1(){
        this.setPizzaName("CaliforniaPizza1");
    }
}
public class ChicagoPizza1 extends Pizza {
    public ChicagoPizza1(){
        this.setPizzaName("ChicagoPizza1");
    }


    @Override
    public void bake(){
        System.out.println("ChicagoPizza1 烘烤流程变啦");
    }
}
public class NYPizza1 extends Pizza {
    public NYPizza1(){
        this.setPizzaName("NYPizza1");
    }
}

public class NYPizza2 extends Pizza {
    public NYPizza2(){
        this.setPizzaName("NYPizza2");
    }
}
public class Pizza {
    private String pizzaName;

    public String getPizzaName() {
        return pizzaName;
    }

    public void setPizzaName(String pizzaName) {
        this.pizzaName = pizzaName;
    }

    public void prepare(){
        System.out.println("准备:"+ pizzaName);
    }

    public void bake(){
        System.out.println("烘烤......");
    }

    public void cut(){
        System.out.println("切片.....");
    }

    public void box(){
        System.out.println("装盒.......");
    }

}

public class ChicagoPizzaStore extends PizzaStore {
    @Override
    protected Pizza createPizza(String type) {
        Pizza pizza = null;
        if(type.equals("ChicagoPizza1")){
            pizza = new ChicagoPizza1();
        }
        return pizza;
    }
}
public class NYPizzaStore extends PizzaStore {
    @Override
    protected Pizza createPizza(String type) {
        Pizza pizza = null;
        if(type.equals("NY1")){
            pizza = new NYPizza1();
        }else if(type.equals("NY2")){
            pizza = new NYPizza2();
        }
        return pizza;
    }
}
public abstract class PizzaStore {

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

    protected abstract Pizza createPizza(String type);
}
public class MainTest {
    public static void main(String[] args) {
        PizzaStore pizzaStore1 = new NYPizzaStore();
        pizzaStore1.orderPizza("NY1");

        PizzaStore pizzaStore2 = new ChicagoPizzaStore();
        pizzaStore2.orderPizza("ChicagoPizza1");
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值