工厂设计模式

简单工厂、工厂方法模式、抽象工厂模式
摘要由CSDN通过智能技术生成

一、主要解决的问题场景

1、实例化对象不使用new,用工厂方法代替

2、将选择实现类、创建对象统一管理控制,从而将调用者跟我们的实现类解耦

二、三种工厂模式

2.0 案例场景

我们建造一个CAR汽车类,然后又很多品牌的汽车将其实现,消费者会去购买对应的汽车品牌,我们一般的处理办法如下:

//定义接口CAR
public interface Car {
   
    void getCarInfo();
}

//多种实现类
public class Tesla implements Car {
   
    @Override
    public void getCarInfo() {
   
        System.out.println("购买一辆特斯拉!");
    }
}
public class Lamborghini implements Car {
   
    @Override
    public void getCarInfo() {
   
        System.out.println("购买一辆兰博基尼-毒药!");
    }
}
public class Bugatti implements Car {
   
    @Override
    public void getCarInfo() {
   
        System.out.println("购买一辆布加迪-威龙!");
    }
}

消费者调用的时候就需要直接new对象

@Test
public void testConsumer() {
   
    Car car1 = new Tesla();
    Car car2 = new Lamborghini();
    Car car3 = new Bugatti();
    car1.getCarInfo(); //log:购买一辆特斯拉!
    car2.getCarInfo(); //log:购买一辆兰博基尼-毒药!
    car3.getCarInfo(); //log:购买一辆布加迪-威龙!
}

new就意味着创建,从生活角度看,也不可能让消费者自己从0到1生成自己想要的汽车。

从代码角度来看,调用方和我们的实现类之间的耦合性很高,如果类参数很多,这会非常的麻烦,代码也会冗余。

违背依赖倒置原则和迪米特原则。

2.1 简单工厂

那么我们可以使用一个工厂模式,将实现方式封装在里面,对外只提供一个或多个方法,消费者只需将自己的需求传递过来即可。

/**
 * 汽车品牌枚举:让客户选择品牌,保证在工厂生产范围内
 */
@Getter
@AllArgsConstructor
public enum CarBrandEnum {
   
    TESLA("Tesla", "世界上最'安全'的电动车,就是刹不住"),
    LAMBORGHINI("Lamborghini", "发售限量款的兰博基尼-毒药,先到先得"),
    BUGATTI("Bugatti", "发售限量款的布加迪威龙,先到先得");

    /**
     * 品牌名称
     */
    private String brandName;

    /**
     * 品牌描述
     */
    private String desc;
}

/**
 * 汽车工厂类
 */
public class CarFactory {
   

    /**
     * 从汽车工厂获取汽车
     * @param brandEnum 品牌枚举
     * @return 返回对应的汽车类
     */
    public static Car getCar(CarBrandEnum brandEnum) {
   
        switch (brandEnum) {
   
            case TESLA:
                return new Tesla();
            case LAMBORGHINI:
                return new Lamborghini();
            case BUGATTI:
                return new Bugatti();
            default:
                return null;
        }
    }
}

/**
 * 消费者调用
 */
@Test
public void testConsumer() {
   
    Car car = CarFactory.getCar(CarBrandEnum.BUGATTI);
    car.getCarInfo(); //log:Bugatti:发售限量款的布加迪威龙,先到先得
}

如果我们需要新增一个Mercedes-Benz梅赛德斯-奔驰类,就不得不对getCar(CarBrandEnum brandEnum)方法进行修改,所以我们可以在汽车工厂类中提供多个方法,调用方只是调用不同的方法。

/**
 * 获取奔驰汽车
 */
/**
 * 汽车工厂类
 */
public class CarFactory {
   

    /**
     * 奔驰车获取方法
     */
    public static Car getBenz() {
   
    	return new Benz();
	}
    
    //……其他的汽车品牌的获取方法
}
简单工厂调用图
在这里插入图片描述

以上就是简单工厂的模式,简单工厂也被成为静态工厂,但是有弊端:

需求变更,必须修改原类或者原类中的方法,违背开闭原则

2.2 工厂方法模式

为了解决简单工厂的开闭问题,我们可以再加一层工厂接口,每个品牌有自己的工厂,消费者根据需求去调用对应车品牌的工厂即可,毕竟没有什么东西是加一层解决不了的,如果不行,那就加两层。

工厂方法模式
在这里插入图片描述
/**
 * 工厂方法接口
 */
public interface MethodFactory {
   
    Car getCar();
}

/**
 * @兰博基尼工厂实现类,内部实现制造兰博基尼-毒药
 */
public class LamborghiniFactory implements MethodFactory {
   
    @Override
    public Car getCar() {
   
        return new Lamborghini();
    }
}

/**
 * 消费者调用
 */
@Test
public void testConsumer() {
   
    MethodFactory factory = new LamborghiniFactory();
    Car car = factory.getCar();
    car.getCarInfo(
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值