一,简介

工厂模式,顾明思议,就是通过通过工厂来创建对象,在java中万事万物皆对象,这些对象都需要创建,如果我们直接使用new或者反射或者系列化来创建对象就会导致我们的程序耦合度特别严重,如果我们的一个对象变了,那么在程序里面与之相关的对象都需要变化,严重违背了我们java的开闭原则,因此我们借助工厂来创建对象,程序中直接通过工厂来获取对象,如果我们的对象需要改变,只需要改变工厂里面的对象就可以了,避免了牵一发而动全身的问题,彻底和对象解耦,因此可以总结为工厂模式最大的优点为解耦。

二,分类

工厂模式的分类可以分为以下三类

①简单工厂

②工厂方法

③抽象工厂

严格意义上说抽象工厂应该是设计模式里面单独的一个模式,这里合在一起说

三,简单工厂

简单工厂是根据传入的集体类型生成具体的对象,假如我们需要一个水果工厂,我们需要根据我们传入的类型来动态的生成对应的对象,需要的角色有

①接口

②水果实现类

③工厂

④使用者

下面我们来详细解说

(1)水果抽象接口

package com.factory.simplefactory;

/**
 * @program: factory
 * @description:水果工厂接口
 * @author: Mr ZHAN
 * @create: 2022-06-09 17:15
 **/
public interface Fruit {
    void whatIm();
}

(2)实现类

假如有三种水果,apple,banana,orangle,我们对这三个品种分别创建实现类

package com.factory.simplefactory;

/**
 * @program: factory
 * @description:
 * @author: Mr ZHAN
 * @create: 2022-06-09 17:22
 **/
 class Apple  implements Fruit{
    @Override
    public void whatIm() {
        System.out.println("我是苹果");
    }
}



 class Orangle implements Fruit{
    @Override
    public void whatIm() {
        System.out.println("我是橘子");
    }
}



 class Banana implements Fruit{
    @Override
    public void whatIm() {
        System.out.println("我是香蕉");
    }
}


(3)工厂

package com.factory.simplefactory;

/**
 * @program: factory
 * @description:
 * @author: Mr ZHAN
 * @create: 2022-06-09 17:25
 **/
public class FruitFactory {
    
    
    public static Object createFruit(String type){
        if (type.equals("apple")){
            return new Apple();
        }else if (type.equals("banabna")){
            return new Banana();
        }else if (type.equals("orange")){
            return new Orangle();
        }
        return  null;
        
    }
}

细心的小伙伴到这已经发现,此种模式存在弊端,我们后续来说

(4)使用者

鉴于使用者那就非常简单了,直接调用水果工厂的静态方法就可以

/**
 * @program: factory
 * @description:
 * @author: Mr ZHAN
 * @create: 2022-06-09 17:31
 **/
public class SimpleFactoryTest {
    public static void main(String[] args) {
        Apple apple = (Apple)FruitFactory.createFruit("apple");
        apple.whatIm();
    }
}

总结:简单工厂这种模式虽然解决了创建对象的问题并且也达到了我们之前虽说的解耦的目的,但是也存在一个问题,假如我们有多个对象需要从工厂获取,我们不可能继续在工厂里面进行判断,这样的话,几个对象还可以,但是有多个呢,很明显,多个对象就需要多个if,很显然这样的代码维护起来也比较困难,也会违反我们的开闭原则,因此我们需要寻找其他的方法来实现。

四,工厂方法

工厂方法意味着就是我们可以将简单工厂进行拆分,每一个对象有一个工厂,分而治之,需要的角色有

①抽象类或者接口---->与上面一样,省略

②水果工厂

③每一个抽象类的工厂

③使用者

(1)水果工厂

public interface FruitFactory {
    Fruit getFruit();
}

(2)抽象类工厂

/**
 * @program: factory
 * @description:
 * @author: Mr ZHAN
 * @create: 2022-06-09 17:42
 **/
public class AppleFactory  implements  FruitFactory{

    @Override
    public  Fruit getFruit() {
        return new Apple();
    }
}

其余的工厂类与上面一致

(3)使用者

/**
 * @program: factory
 * @description:
 * @author: Mr ZHAN
 * @create: 2022-06-09 17:50
 **/
public class FactoryTest {
    public static void main(String[] args) {
        AppleFactory factory = new AppleFactory();
        Fruit fruit = factory.getFruit();
        fruit.whatIm();
    }
}

总结:抽象方法虽然解决了创建对象的问题,并且也解耦,并且遵循了开闭原则,但是同样的我们如果有多个对象要创建,那么也会有多个工厂,显然不是办法。

五,抽象工厂 

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

①抽象产品
②具体产品
③抽象工厂
④具体工厂

使用说明:

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

(1)cpu接口和实现类:

public interface Cpu {  
    void run();  
  
    class Cpu650 implements Cpu {  
        @Override  
        public void run() {  
            System.out.println("650 也厉害");  
        }  
    }  
  
    class Cpu825 implements Cpu {  
        @Override  
        public void run() {  
            System.out.println("825 更强劲");  
        }  
    }  
}  

(2)屏幕接口和实现类:

public interface Screen {  
  
    void size();  
  
    class Screen5 implements Screen {  
  
        @Override  
        public void size() {  
            System.out.println("" +  
                    "5寸");  
        }  
    }  
  
    class Screen6 implements Screen {  
  
        @Override  
        public void size() {  
            System.out.println("6寸");  
        }  
    }  
}  

(3)抽象工厂接口:

public interface PhoneFactory {  
  
    Cpu getCpu();//使用的cpu  
  
    Screen getScreen();//使用的屏幕  
}  

(4)小米手机工厂:

public class XiaoMiFactory implements PhoneFactory {  
    @Override  
    public Cpu.Cpu825 getCpu() {  
        return new Cpu.Cpu825();//高性能处理器  
    }  
  
    @Override  
    public Screen.Screen6 getScreen() {  
        return new Screen.Screen6();//6寸大屏  
    }  
}  

(5)红米手机工厂:

public class HongMiFactory implements PhoneFactory {  
  
    @Override  
    public Cpu.Cpu650 getCpu() {  
        return new Cpu.Cpu650();//高效处理器  
    }  
  
    @Override  
    public Screen.Screen5 getScreen() {  
        return new Screen.Screen5();//小屏手机  
    }  
}  

(6)使用工厂生产产品:

public class PhoneApp {  
    public static void main(String[] args){  
        HongMiFactory hongMiFactory = new HongMiFactory();  
        XiaoMiFactory xiaoMiFactory = new XiaoMiFactory();  
        Cpu.Cpu650 cpu650 = hongMiFactory.getCpu();  
        Cpu.Cpu825 cpu825 = xiaoMiFactory.getCpu();  
        cpu650.run();  
        cpu825.run();  
  
        Screen.Screen5 screen5 = hongMiFactory.getScreen();  
        Screen.Screen6 screen6 = xiaoMiFactory.getScreen();  
        screen5.size();  
        screen6.size();  
    }  
}  

以上例子可以看出,抽象工厂可以解决一系列的产品生产的需求,对于大批量,多系列的产品,用抽象工厂可以更好的管理和扩展。

六,总结

工厂模式可以实现我们的代码与核心逻辑进行解耦,但是不用的类型使用的场景不同

①如果我们是小型的项目,并且需要生产得同一类对象不是那么多是,简单工厂和工厂方法是最好的选择

②相反如果我们的项目比较复杂,适用于一系列大批量对象的生产。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐