工厂模式
不使用工厂模式
代码模拟买车
public interface Car {
void name();
}
public class WuLing implements Car {
@Override
public void name() {
System.out.println("五菱宏光");
}
}
public class Tesla implements Car{
@Override
public void name() {
System.out.println("特斯拉");
}
}
//消费者买车
public class Consumer {
public static void main(String[] args) {
Car car1 = new WuLing();
Car car2 = new Tesla();
car1.name();
car2.name();
}
}
一开始,我们买车,车是我们自己new出来的,我们即是创建者又是调用者
简单工厂模式(静态工厂)
使用简单工厂模式后,我们要买车,我们是调用者,车是由车工厂创建出来的,车工厂是创建者
public interface Car {
void name();
}
public class Tesla implements Car{
@Override
public void name() {
System.out.println("特斯拉");
}
}
public class WuLing implements Car {
@Override
public void name() {
System.out.println("五菱宏光");
}
}
//简单工厂模式 如果要添加新产品就需要修改代码 不满足开闭原则
public class CarFactory {
//方法一
public Car getWuLing(){
return new WuLing();
}
public Car getTesla(){
return new Tesla();
}
//方法二
public Car getCar(String s){
if (s.equals("五菱宏光")){
return new WuLing();
}else if (s.equals("特斯拉")){
return new Tesla();
}else return null;
}
}
//消费者买车
public class Consumer {
public static void main(String[] args) {
/*//一开始
Car car1 = new WuLing();
Car car2 = new Tesla();
car1.name();
car2.name();*/
//简单工厂
CarFactory carFactory = new CarFactory();
//方法一
Car car1 = carFactory.getWuLing();
Car car2 = carFactory.getTesla();
//方法二
// Car car1 = carFactory.getCar("五菱宏光");
// Car car2 = carFactory.getCar("特斯拉");
car1.name();
car2.name();
}
}
使用简单工厂模式后,创建者与调用者分离了,但是想要增加新产品,还需要改变原来代码
-
简单工厂模式将创建者与调用者分离
- 由工厂(创建者)创建车对象,我们(调用者)去调用工厂给出的方法得到这个车对象
-
简单工厂模式违反了开闭原则
- 如果还想增加新车,需要改动工厂中创建车对象的代码
工厂方法模式
使用工厂方法模式后,我们买车,去找这个品牌的工厂(比如买特斯拉就去找TeslaFactory),这些品牌的工厂都实现了CarFactory接口,这时新增产品就不需要改变原来(五菱宏光,特斯拉)的代码,只需要去实现Car和CarFactory接口,相比于简单工厂模式,遵循了开闭原则,结构更清晰,但是代码复杂度增加
public interface Car {
void name();
}
public interface CarFactory {
Car getCar();
}
public class Tesla implements Car{
@Override
public void name() {
System.out.println("特斯拉");
}
}
public class TeslaFactory implements CarFactory {
@Override
public Car getCar() {
return new Tesla();
}
}
public class WuLing implements Car {
@Override
public void name() {
System.out.println("五菱宏光");
}
}
public class WuLingFactory implements CarFactory {
@Override
public Car getCar() {
return new WuLing();
}
}
//消费者买车
public class Consumer {
public static void main(String[] args) {
/*//一开始
Car car1 = new WuLing();
Car car2 = new Tesla();
car1.name();
car2.name();*/
/* //简单工厂模式
CarFactory carFactory = new CarFactory();
//方法一
Car car1 = carFactory.getWuLing();
Car car2 = carFactory.getTesla();
//方法二
// Car car1 = carFactory.getCar("五菱宏光");
// Car car2 = carFactory.getCar("特斯拉");
car1.name();
car2.name();*/
//工厂方法模式
WuLingFactory wuLingFactory = new WuLingFactory();
Car car1 = wuLingFactory.getCar();
TeslaFactory teslaFactory = new TeslaFactory();
Car car2 = teslaFactory.getCar();
car1.name();
car2.name();
}
}
- 工厂方法模式遵循开闭原则进一步解耦 车工厂(接口),不同品牌的车工厂去实现车工厂接口,增加新品牌的车只需要新品牌工厂去实现车工厂接口,我们(调用者)再从某品牌车工厂获取
- 工厂方法模式结构更加清晰,但复杂度更高
抽象工厂模式
抽象工厂:围绕一个超级工厂去创建其他工厂,这个超级工厂又是其他工厂的工厂 进一步抽象
整体结构
代码
//抽象工厂
public interface ProductFactory {
//生产汽车
CarProduct carProduct();
//生产摩托车
BikeProduct bikeProduct();
}
//汽车产品
public interface CarProduct {
void getCar();
}
//摩托车产品
public interface BikeProduct {
void getBike();
}
public class TeslaFactory implements ProductFactory{
@Override
public CarProduct carProduct() {
return new TeslaCar();
}
@Override
public BikeProduct bikeProduct() {
return new TeslaBike();
}
}
public class TeslaCar implements CarProduct {
@Override
public void getCar() {
System.out.println("获得特斯拉汽车");
}
}
public class TeslaBike implements BikeProduct {
@Override
public void getBike() {
System.out.println("获得特斯拉摩托车");
}
}
public class WuLingFactory implements ProductFactory {
@Override
public CarProduct carProduct() {
return new WuLingCar();
}
@Override
public BikeProduct bikeProduct() {
return new WuLingBike();
}
}
public class WuLingCar implements CarProduct{
@Override
public void getCar() {
System.out.println("获得五菱宏光汽车");
}
}
public class WuLingBike implements BikeProduct {
@Override
public void getBike() {
System.out.println("获得五菱宏光摩托车");
}
}
public class Consumer {
public static void main(String[] args) {
WuLingFactory wuLingFactory = new WuLingFactory();
System.out.println("--------获得五菱宏光产品-------------");
CarProduct wuLingCar = wuLingFactory.carProduct();//通过WuLing工厂生产五菱宏光汽车
wuLingCar.getCar();
BikeProduct wuLingBike = wuLingFactory.bikeProduct();//通过WuLing工厂生产五菱宏光摩托车
wuLingBike.getBike();
System.out.println("-------获得特斯拉产品--------------");
TeslaFactory teslaFactory = new TeslaFactory();
CarProduct teslaCar = teslaFactory.carProduct();//通过Tesla工厂生产五菱宏光汽车
teslaCar.getCar();
BikeProduct teslaBike = teslaFactory.bikeProduct();//通过Tesla工厂生产五菱宏光摩托车
teslaBike.getBike();
}
}
/*
* --------获得五菱宏光产品-------------
获得五菱宏光汽车
获得五菱宏光摩托车
-------获得特斯拉产品--------------
获得特斯拉汽车
获得特斯拉摩托车
* */
抽象工厂ProductFactory
是WuLingFactory
和TeslaFactory
的工厂
抽象工厂不可以增加产品(比如说再增加个自行车),这样就又要修改抽象工厂ProductFactory
中的代码
抽象工厂可以增加产品族(比如再增加个宝马汽车和宝马摩托车产品)只需要让宝马Factory
去实现抽象工厂ProductFactory
接口即可
- 优点
- 将一个系列的产品统一到一起创建(这里统一创建Car,Bike)
- 不用关心创建细节
- 缺点
- 增加新产品困难(需要改代码)
总结
-
作用
- 将创建者与调用者分离
-
核心
- 实例化对象不new,使用工厂方法代替
- 创建对象进行统一管理,将调用者跟实现类解耦
-
三种模式
-
简单工厂模式
-
对于新增产品需要改动代码
-
没遵循开闭原则(添加新产品会改动工厂中的代码),但是实际使用最多
-
-
工厂方法模式
- 通过增加新工厂,新类实现扩展(不改变原有代码)
- 代码,结构复杂度都比简单工厂模式高;但是,结构很清晰
- 抽象工厂模式
- 可以增加产品族,不可以增加新产品 可以增加新品牌,不可以增加新产品(会更改代码)
- 工厂的工厂
-