23种设计模式之——工厂设计模式

前言:记得大二时上过一门设计模式的课,当时听的那叫一个懵逼。。如今工作半年了,想把东西再捡起来,顺便记录一下。。工厂模式是平时接触的多一点的,就从工厂模式开始吧…

什么是工厂设计模式?

工厂设计模式,顾名思义,就是用来生产对象的,是一种创建型设计模式。在面向对象语言中,万物皆对象,这些对象都需要创建,如果创建的时候直接new该对象,就会对该对象耦合严重,假如我们要更换对象,所有new对象的地方都需要修改一遍,这显然违背了软件设计的开闭原则,如果我们使用工厂来生产对象,我们就只和工厂打交道就可以了,彻底和对象解耦,如果要更换对象,直接在工厂里更换该对象即可,达到了与对象解耦的目的;所以说,工厂模式最大的优点就是:解耦

工厂模式又包含三种:

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

简单工厂设计模式

定义:一个工厂方法,生存某类的对象。

角色:

  1. 抽象产品
  2. 具体产品
  3. 具体工厂
  4. 产品使用者

工厂模式是用来创建某一类对象的工厂,因此需要首先抽象产品,比如苹果,橘子都属于水果,因此我们可以先抽象出一个水果类,再定义一个水果工厂,用来生产不同的水果

水果接口:

public interface Fruit{
    void eat();  // 定义一个水果被吃了的方法
}

具体类:苹果或者橘子

public class Apple implement Fruit{
    @Override
    void eat(){
        System.out.print("苹果被吃了");
    }
}
public class Orange implement Fruit{
    @Override
    void eat(){
        System.out.print("橘子被吃了");
    }
}

具体工厂:水果工厂类

public class FruitFactory{
    // 提供一个静态方法给外部使用
    public static Fruit createFruit(String type){
        switch(type){
            case 'apple':
                return new Apple();
                break;
            case 'orange':
                return new Orange();
                break;
            // ... 还可以有很多
            default:
                System.out.print("暂不支持生产该类型");
        }
    }
}

产品使用:

Apple apple = (Apple)FruitFactory.createFruit("apple");
apple.eat();// 苹果被吃了

以上就是简单工厂模式,其思想就是将类的创建交个工厂,当需要某个类时,从工厂里取。简单工厂模式虽然简单,但有其弊端,就是当我需要生产一种新的水果产品,需要修改工厂,这显然违反了六大设计原则的开闭原则。

为解决该问题我们介绍第二种工厂模式:

工厂方法设计模式

定义:将工厂提取成一个接口或抽象类,具体生产什么产品由子类决定;

角色:

  1. 抽象产品
  2. 具体产品
  3. 抽象工厂
  4. 具体工厂

和简单工厂类一样,我们需要将产品抽象出来,还用水果类,这次我们将工厂也抽象出来,具体生产什么由子类决定:

省略水果接口,苹果类,橘子类。。。

工厂接口

public interface FruitFactory{
    Fruit createFruit();// 生产水果的方法
}

苹果工厂

public AppleFactory implements FruitFactory{
    @Override
    Fruit createFruit(){
        return new Apple();
    }
}
// 橘子工厂
public OrangeFactory implements FruitFactory{
    @Override
    Fruit createFruit(){
        return new Orange();
    }
}

使用产品

AppleFactory af=new AppleFactory();
Apple apple = af.createFruit();

以上这种方式,虽然解耦了,也遵循了开闭原则,但是问题根本还是没有解决啊,换汤没换药,如果我需要的产品很多的话,需要创建非常多的工厂,所以这种方式的缺点也很明显;于是我们再来看最后一种工厂模式:

抽象工厂设计模式

定义:为创建一组相关或者是相互依赖的对象提供的一个接口,而不需要指定它们的具体类。
角色:

  1. 抽象产品
  2. 具体产品
  3. 抽象工厂
  4. 具体工厂

抽象工厂和工厂方法的模式基本一样,区别在于,工厂方法是生产一个具体的产品,而抽象工厂可以用来生产一组相同,有相对关系的产品;重点在于一组,一批,一系列;举个例子,假如生产小米手机(一不小心就给小米打了个广告~),小米手机有很多系列,小米note、红米note等;假如小米note生产需要的配件有825的处理器,6英寸屏幕,而红米只需要650的处理器和5寸的屏幕就可以了;用抽象工厂来实现:

cpu接口和实现类

public interface Cpu {
    void run();

    class Cpu650 implements Cpu {
        @Override
        public void run() {
            System.out.print("650cpu运行了"); 
        }
    }

    class Cpu825 implements Cpu {
        @Override
        public void run() {
            System.out.print("825cpu运行了"); 
        }
    }
}

屏幕接口和实现类

public interface Screen {

    void size();

    class Screen5 implements Screen {

        @Override
        public void size() {
            System.out.print("5寸的显示屏");
        }
    }

    class Screen6 implements Screen {

        @Override
        public void size() {
           System.out.print("6寸的显示屏");
        }
    }
}

工厂接口

public interface PhoneFactory {

    Cpu getCpu();//使用的cpu

    Screen getScreen();//使用的屏幕
}

具体工厂实现类:小米手机工厂类

public class XiaoMiFactory implements PhoneFactory {
    @Override
    public Cpu getCpu() {
        return new Cpu825();//高性能处理器
    }

    @Override
    public Screen getScreen() {
        return new Screen6();//6寸大屏
    }
}

具体工厂实现类:红米手机工厂类

public class HongMiFactory implements PhoneFactory {

    @Override
    public Cpu getCpu() {
        return new Cpu650();//高效处理器
    }

    @Override
    public Screen getScreen() {
        return new Screen5();//小屏手机
    }
}

现在可以在两种cpu和两种屏幕任意组合,得到相应性能的手机,以上例子可以看出,抽象工厂可以解决一系列的产品生产的需求,对于大批量,多系列的产品,用抽象工厂可以更好的管理和扩展;

总结

1、对于简单工厂和工厂方法来说,两者的使用方式实际上是一样的,如果对于产品的分类和名称是确定的,数量是相对固定的,推荐使用简单工厂模式;
2、抽象工厂用来解决相对复杂的问题,适用于一系列、大批量的对象生产;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章