Bootstrap

Java设计模式-工厂模式

1、简介

工厂模式是一种创建型设计模式, 是用工厂方法代替new操作的一种模式。工厂模式能大量减少if-else,减少大量冗余代码,也能够更好的提高代码复用性 ,减少耦合,也就是我们常说的高内聚低耦合

2、分类和比较

工厂模式可以分为:简单工厂模式,工厂方法模式、抽象工厂模式

分类介绍
简单工厂模式用于生产同一等级结构中得任何产品(对于生产新的产品,需要修改已有得代码)
工厂方法模式用于生产同一等级结构中得固定产品(支持增加任意产品)
抽象工厂模式用于生产不同产品族得全部产品

3、简单工厂模式

/**
 * 汽车接口
 */
public interface ICar {
    void carRun();
}


/**
 * @Author charles.yao
 * @Description 奥迪车
 * @Date 2023/1/29 13:43
 */
public class AudiCar implements ICar {
    @Override
    public void carRun() {
        System.out.println("奥迪车在跑~");
    }
}


/**
 * @Author charles.yao
 * @Description 奔驰车
 * @Date 2023/1/29 13:44
 */
public class BenzCar implements ICar {
    @Override
    public void carRun() {
        System.out.println("奔驰车再跑~");
    }
}

简单工厂实现

/**
 * @Author charles.yao
 * @Description 汽车工厂
 * @Date 2023/1/29 13:45
 */
public class CarFactory {
    /**
     * 创建一个汽车
     *
     * @param num
     * @return
     */
    public static ICar createCar(Integer num) {
        if (num == 1) {
            return new AudiCar();
        } else {
            return new BenzCar();
        }
    }
}

简单测试一下

/**
 * @Author charles.yao
 * @Description 简单工厂测试
 * @Date 2023/1/29 13:48
 */
public class CarTest {
    public static void main(String[] args) {
        ICar car = CarFactory.createCar(1);
        car.carRun();
    }
}

总结:

1、简单工厂模式也叫静态工厂模式,一般是使用静态方法,通过接收不同的参数来返回不同得实例对象

2、如果需要增加新的产品,需要修改代码

4、工厂方法模式

car类使用上边类即可

工厂方法类接口

/**
 * 工厂方法接口类
 */
public interface CarFactory {
    ICar createCar();
}

实现类


/**
 * @Author charles.yao
 * @Description 奥迪工厂类
 * @Date 2023/1/29 13:56
 */
public class AudiCarFactory implements  CarFactory{
    @Override
    public ICar createCar() {
        return new AudiCar();
    }
}

/**
 * @Author charles.yao
 * @Description 奔驰工厂类
 * @Date 2023/1/29 13:57
 */
public class BenzFactory implements CarFactory{
    @Override
    public ICar createCar() {
        return new BenzCar();
    }
}

测试类


/**
 * @Author charles.yao
 * @Description 工厂方法类
 * @Date 2023/1/29 13:57
 */
public class MethodTest {
    public static void main(String[] args) {
        CarFactory audiCarFactory = new AudiCarFactory();
        CarFactory benzFactory = new BenzFactory();
        audiCarFactory.createCar().carRun();
        benzFactory.createCar().carRun();

    }

总结:
优点:

  • 用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程。
  • 灵活性增强,对于新产品的创建,只需多写一个相应的工厂类。
  • 典型的解耦框架。高层模块只需要知道产品的抽象类,无须关心其他实现类,满足迪米特法则、依赖倒置原则和里氏替换原则。

缺点:

  • 类的个数容易过多,增加复杂度
  • 增加了系统的抽象性和理解难度
  • 抽象产品只能生产一种产品,此弊端可使用抽象工厂模式解决

5、抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

  1. 用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)
  2. 抽象工厂模式是工厂方法模式的升级版本,在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。

发动机相关

/**
 * 发动机接口
 */
public interface IEngine {
    void run();
    void start();
}


/**
 * @Author charles.yao
 * @Description 高功率发动机
 * @Date 2023/2/7 16:08
 */
public class HighEngine implements IEngine {
    @Override
    public void run() {
        System.out.println("高功率发动机在运行");
    }

    @Override
    public void start() {
        System.out.println("高功率发动机启动啦~");
    }
}



/**
 * @Author charles.yao
 * @Description 低功率发动机
 * @Date 2023/2/7 16:09
 */
public class LowEngine implements IEngine {
    @Override
    public void run() {
        System.out.println("低功率发动机运行ing");
    }

    @Override
    public void start() {
        System.out.println("低功率发动机启动啦~");
    }
}

座椅相关


/**
 * 座椅接口
 */
public interface ISeat {
    void msg();
}


/**
 * @Author charles.yao
 * @Description 高端座椅类
 * @Date 2023/2/7 16:11
 */
public class HighSeat implements ISeat{
    @Override
    public void msg() {
        System.out.println("高端座椅自动加热ing");
    }
}

/**
 * @Author charles.yao
 * @Description 低端座椅
 * @Date 2023/2/7 16:11
 */
public class LowSeat implements ISeat {
    @Override
    public void msg() {
        System.out.println("低端座椅屁都没有,凑合坐着吧");
    }
}

工厂相关,工厂能生成高端低端,汽车相关不同产品


/**
 * @Author charles.yao
 * @Description 抽象工厂接口
 * @Date 2023/2/7 16:13
 */
public interface ICarFactory {
    ISeat createSeat();
    IEngine createEngine();
}


/**
 * @Author charles.yao
 * @Description 低端工厂类
 * @Date 2023/2/7 16:17
 */
public class LowCarFactory implements ICarFactory {
    @Override
    public ISeat createSeat() {
        return new LowSeat();
    }

    @Override
    public IEngine createEngine() {
        return new LowEngine();
    }
}
/**
 * @Author charles.yao
 * @Description 高端工厂类
 * @Date 2023/2/7 16:16
 */
public class HighCarFactory implements ICarFactory {
    @Override
    public ISeat createSeat() {
        return new HighSeat();
    }

    @Override
    public IEngine createEngine() {
        return new HighEngine();
    }
}

测试类:


/**
 * @Author charles.yao
 * @Description 抽象工厂模式test
 * @Date 2023/2/7 16:18
 */
public class AbstractFactoryTest {
    public static void main(String[] args) {
        ICarFactory highCarFactory = new HighCarFactory();
        IEngine engine = highCarFactory.createEngine();
        engine.start();
        engine.run();
        ISeat seat = highCarFactory.createSeat();
        seat.msg();

    }
}

6、springboot中应用

工厂模式+策略模式 会涉及公司代码,我会删除部分逻辑,请见谅

策略接口:


/**
 * 股东导入公共接口
 */
public interface HolderImportInterface {
    /**
     * 处理股东数据
     *
     * @param stockBasisBOList
     */
    void dealHolderData(List<StockBasisBO> stockBasisBOList, Integer comCodeType);

    //获取类型
    Integer getType();

}

实现类(可以使用若干类,我就写了一个)

@Slf4j
@Service
public class AService  implements HolderImportInterface {

    @Override
    public void dealHolderData(List<StockBasisBO> stockBasisBOList, Integer comCodeType) {
       //数据处理逻辑
    }

    @Override
    public Integer getType() {
				//使用枚举类,
        return HolderTypeEnum.DERI_STK_LTD_GEN.type();
    } 

  }

工厂类


/**
 * @Author charles.yao
 * @Description 股东类数据导入工厂类
 * @Date 2022/4/22 10:39
 */
@Component
public class HolderImportFactory implements ApplicationContextAware {
    public Map<Integer, HolderImportInterface> holderImportMap = new ConcurrentHashMap<>();

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        //根据接口类型返回相应的所有bean
        Map<String, HolderImportInterface> map = applicationContext.getBeansOfType(HolderImportInterface.class);
        for (Map.Entry<String, HolderImportInterface> data : map.entrySet()) {
            Integer keyType = data.getValue().getType();
            holderImportMap.put(keyType, data.getValue());
        }
    }

    /**
     * 获取股东导入service
     *
     * @param type
     * @return
     */
    public HolderImportInterface getHolderImport(Integer type) {
        HolderImportInterface holderImportInterface = holderImportMap.get(type);
        if (ObjectUtil.isNotNull(holderImportInterface)) {
            return holderImportInterface;
        } else {
            return null;
        }
    }
}
;