设计模式--------工厂模式

设计模式--------工厂模式

介绍工厂模式的四大问题

  • 现在的写法有什么问题吗?
  • 为什么要用工厂模式?
  • 什么是工厂模式?
  • 工厂模式有什么好处?

工厂模式细分

  • 简单工厂模式
  • 工厂方法模式
  • 抽象工厂模式

采用一个案例来说明问题

  • 现有一个披萨店,需要根据不同的需求制作披萨

常规思路

  • 创建一个抽象Pizza类,其中有一系列制作步骤方法,不同种类的Pizza继承此类
  • 创建一个PizzaStore类
    • orderPizza(String type) : 根据传入的type制作不同种类的Pizza
    public Pizza OrderPizza(String type) {
        Pizza pizza = null;
        if (type.equals("apple")) {
            pizza = new ApplePizza();
        } else if (type.equals("banana")) {
            pizza = new BananaPizza();
        }
        
        pizza.cut();
        pizza.pack();
        return pizza;
    }

现在的写法有什么问题吗?

  • 每当有新的种类Pizza,就会修改当前的代码
  • 应该将变化的和不变化的分来封装起来

简单工厂模式

  • 创建一个工厂类,单独对创建Pizza进行处理,以达到每次新增只需修改工厂类就可以

Pizza抽象类

public abstract class Pizza {

    public void cut() {
        System.out.println("正在切Pizza...");
    }
    public void pack() {
        System.out.println("正在打包Pizza...");
    }
}

Pizza工厂类

public class PizzaFactory {
    public Pizza createPizza(String type) {
        Pizza pizza = null;
        if (type.equals("apple")) {
            pizza = new ApplePizza();
        } else if (type.equals("banana")) {
            pizza = new BananaPizza();
        }

        return pizza;
    }
}

Pizza商店类

public class PizzaStore {

    private PizzaFactory pizzaFactory;

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

    public Pizza orderPizza(String type) {
        Pizza pizza = pizzaFactory.createPizza(type);
        pizza.cut();
        pizza.pack();
        return pizza;
    }
}

Main

public class Main {
    public static void main(String[] args) {
        PizzaFactory pizzaFactory = new PizzaFactory();
        PizzaStore pizzaStore = new PizzaStore(pizzaFactory);
        pizzaStore.orderPizza("apple");
    }
}

简单工厂模式好处和缺点?

  • 简单工厂模式把Pizza中会变化的部分提取了出来,以致以后的新款式的增加不会影响到此类
  • 便于出现类名更改,导致成千上万的类名要改变,只需改工厂中创建的那一处就可以
  • 缺点在于每增加一个类都需要更改工厂类,不符合开闭原则

使用工厂方法模式进行改造(为了便于理解,把一些没用的去除了)

  • 使用工厂方法模式将类的创建转移到了子类中
  • 将具体要创建的类通过一个抽象方法由子类实现

Pizza

public abstract class Pizza {

    public abstract void show();
}

ApplePizza


public class ApplePizza extends Pizza {

    @Override
    public void show() {
        System.out.print("Apple");
    }
}

PizzaFactory

public abstract class PizzaFactory {

    public abstract Pizza createPizza();


}

ApplePizzaFactory

public class ApplePizzaFactory extends PizzaFactory {

    @Override
    public Pizza createPizza() {
        return new ApplePizza();
    }
}

Main

public class Main {

    public static void main(String[] args) {

        PizzaFactory factory = new ApplePizzaFactory();
        Pizza pizza = factory.createPizza();
        pizza.show();
        
    }
}

工厂方法和简单工厂的区别(个人观点)

  • 简单工厂不符合开闭原则,工厂方法符合开闭原则
  • 简单工厂给人一种这个工厂全世界只有一家,它什么都能生产(这就导致每有一个新的就要加一个)
  • 工厂方法给人一种有多家工厂,每个工厂只生产特有的一样或者多样产品(这就使每有一个新的就需要一个新的工厂),你要生产啥就实例化那个工厂以创建产品
  • 工厂方法模式会有很多的类(缺点)

工厂方式的疑惑?

  • 你说简单工厂的方式是为了不new一个对象,为了总的管理new,为了类改变而导致要改变多个new的地方,好,可以理解!
  • 那么工厂方式不是又用了new的方式吗,同样是为了new一个Pizza,为什么不直接new,而要转来转去,还创建一个工厂
  • 解答: 为了创建复杂对象,为了拓展性,简单对象只要new的就不要用工厂方式了

抽象工厂

  • 抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类

各个模式使用场景(个人意见)

  • 简单工厂模式: 因为只有一个工厂,而且是根据type进行创建的,所以只要不怕麻烦,可以让所有的具体产品类都由它生产,虽然这样是违反开闭原则的
  • 工厂模式: 说是解决了开闭原则的模式,细想一下,也只是对于同类产品的更新迭代适用,例如要生产鼠标,那么会有多个品牌的鼠标,每一个工厂对应一个品牌的鼠标,通过具体实例化某一个品牌的工厂来生产我们所需的产品,而不是和简单工厂一样传入xx牌鼠标的type来实例化,但是要生产一个键盘的话,那不是要在工厂抽象类中再创建一个createKeyboard方法吗,然后xx牌工厂继承它,实现自己牌子的键盘,违反了开闭原则,而这样的方式又不叫工厂模式了,也就是下面的模式
  • 抽象工厂模式:就是将一个工厂的多个产品一起作为一系列接口,可以这么说,抽象工厂模式用于拓展不同种类的产品,工厂模式用来拓展同类产品,拓展不同类产品同样会违反开闭原则(如果是生产流水线的工厂的话就不会违反开闭原则,因为流程一般是不变的,可以说抽象工厂就是为了这种模式产生的?)
  • 其实选择什么模式就是根据你要做的东西的规模来决定
    • 简单工厂:要是你是个小卖部,啥都买,那你就用简单工厂,因为同类东西你不一定有多样,何必复杂化呢
    • 工厂模式:只生产某一样东西,多个工厂可以理解为多个品牌的区分,也可以理解为连锁店,多个地区的区分等等,这样同时满足了开闭原则
    • 抽象工厂模式:大工厂,每个工厂有多个产品可以生产,也可以是每个工厂都是生产一个产品的流水线工程,简单的可以分为二类,一是一个工厂就是一个大公司,每个公司生产多个不同产品;二是一个工厂是一个公司某个地区的一个工厂,然后根据不同的地区产品有所变化,产品可以是一系列流水线工程或者是很多产品
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值