-
实现创建者与调用者的分离
以化妆品为例:
-
生产者:
-
一个接口,提供了生产化妆品的方法
public interface Cosmetics {
void productCosmetics();
} -
-
生产的对象:
-
口红
public class Lipstick implements Cosmetics{
public void productCosmetics() {
System.out.println("口红");
}
} -
眼影
public class EyeShadow implements Cosmetics{
public void productCosmetics() {
System.out.println("眼影");
}
}
-
1、传统的方式
图解
-
消费者:
-
消费者要首先把 Lipstick 和 EyeShadow 实例化(new),才能实现对象的方法。
public class Consumer {
public static void main(String[] args) {
Cosmetics lipstick = new Lipstick();
Cosmetics eyeShadow = new EyeShadow();
lipstick.productCosmetics();
eyeShadow.productCosmetics();
}
} -
2、工厂模式(静态工厂模式)
图解
-
化妆品工厂
public class CosmeticsFactory {
public static Cosmetics getCosmeticsFactory(String factory){
if (factory.equals("口红")){
return new Lipstick();
}else if (factory.equals("眼影")){
return new EyeShadow();
}else {
return null;
}
}
} -
消费者:
-
通过化妆品工厂来得到对象的实例化,无需new,来实现对象的方法
public class Consumer {
public static void main(String[] args) {
Cosmetics lipstick = CosmeticsFactory.getCosmeticsFactory("口红");
lipstick.productCosmetics();
Cosmetics eyeShadow = CosmeticsFactory.getCosmeticsFactory("眼影");
eyeShadow.productCosmetics();
}
} -
-
工厂模式缺点:
OOP七大原则之开闭原则:一个软件的实体应对扩展开放,对修改关闭
工厂模式实现不了开闭原则,如果要扩展新的功能,必须修改CosmeticsFactory才能实现
3、工厂方法模式
-
解决工厂模式无法实现开闭原则的问题
图解
-
化妆品工厂
public interface CosmeticsFactory {
Cosmetics getCosmetics();
} -
口红工厂
public class LipstickFactory implements CosmeticsFactory {
public Cosmetics getCosmetics() {
return new Lipstick();
}
} -
眼影工厂
public class EyeShadowFactory implements CosmeticsFactory {
public Cosmetics getCosmetics() {
return new EyeShadow();
}
} -
消费者
public class Consumer {
public static void main(String[] args) {
Cosmetics lipstick = new LipstickFactory().getCosmetics();
lipstick.productCosmetics();
Cosmetics eyeShadow = new EyeShadowFactory().getCosmetics();
eyeShadow.productCosmetics();
}
} -
新增一个产品:
只需要编写一个产品类,例如眉笔,编写一个眉笔工厂继承化妆品工厂,
可在不改动原有代码的基础上扩展功能,实现开闭原则。
4、抽象工厂模式
-
简单工厂模式 和 工厂方法模式 都是用来生产同一等级结构的任意产品
抽象工厂模式 统一创建同一系列的产品,可以创建多个产品家族的多个等级结构的产品
图解
实现
-
产品工厂:
public interface ProductFactory {
//生产手机
Phone productPhone();
//生产电脑
Computer productComputer();
} -
手机:
public interface Phone {
//生产手机屏
void productMobileScreen();
//生产手机外壳
void productPhoneShell();
//生产手机套
void productPhoneSet();
} -
电脑:
public interface Computer {
//生产电脑屏
void productMobileScreen();
//生产电脑外壳
void productPhoneShell();
//生产电脑套
void productPhoneSet();
} -
HUAWEI产品工厂:
public class HUAWEIProductFactory implements ProductFactory {
//实例化HUAWEI手机
public Phone productPhone() {
return new HUAWEIPhone();
}
//实例化HUAWEI电脑
public Computer productComputer() {
return new HUAWEIComputer();
}
} -
ASUS产品工厂:
public class ASUSProductFactory implements ProductFactory {
//实例化ASUS手机
public Phone productPhone() {
return new ASUSPhone();
}
//实例化ASUS电脑
public Computer productComputer() {
return new ASUSComputer();
}
} -
HUAWEI手机:
public class HUAWEIPhone implements Phone {
public void productMobileScreen() {
System.out.println("生产HUAWEI手机屏");
}
public void productPhoneShell() {
System.out.println("生产HUAWEI手机外壳");
}
public void productPhoneSet() {
System.out.println("生产HUAWEI手机套");
}
} -
ASUS手机:
public class ASUSPhone implements Phone {
public void productMobileScreen() {
System.out.println("生产ASUS手机屏");
}
public void productPhoneShell() {
System.out.println("生产ASUS手机外壳");
}
public void productPhoneSet() {
System.out.println("生产ASUS手机套");
}
} -
HUAWEI电脑:
public class HUAWEIComputer implements Computer {
public void productMobileScreen() {
System.out.println("生产HUAWEI电脑屏");
}
public void productPhoneShell() {
System.out.println("生产HUAWEI电脑外壳");
}
public void productPhoneSet() {
System.out.println("生产HUAWEI电脑套");
}
} -
ASUS电脑:
public class ASUSComputer implements Computer {
public void productMobileScreen() {
System.out.println("生产ASUS电脑屏");
}
public void productPhoneShell() {
System.out.println("生产ASUS电脑外壳");
}
public void productPhoneSet() {
System.out.println("生产ASUS电脑套");
}
} -
消费者:
public class Consumer {
public static void main(String[] args) {
//消费者直接操作HUAWEI和ASUS的产品工厂
HUAWEIProductFactory huaweiProductFactory = new HUAWEIProductFactory();
ASUSProductFactory asusProductFactory = new ASUSProductFactory();
//通过工厂生产手机和电脑
//huawei电脑
Computer huaweiComputer = huaweiProductFactory.productComputer();
//asus手机
Phone asusPhone = asusProductFactory.productPhone();
//调用生产的手机和电脑中的方法,操作手机和电脑
huaweiComputer.productMobileScreen();
huaweiComputer.productPhoneShell();
asusPhone.productPhoneShell();
asusPhone.productPhoneSet();
}
}
-
优点:
具体产品在应用层的代码隔离,无需关心创建的细节
将同一系列的产品统一到一起创建
-
缺点:
产品簇中扩展新的产品困难
增加了系统的抽象性和理解难度
5、小结
-
简单工厂模式
-
虽然没有实现开闭原则,但实际使用最多
-
-
工厂方法模式
-
不修改已有类的前提下,可以增加新的工厂类进行扩展
-
-
抽象工厂模式
-
不可以增加产品,可以增加产品族
-
-
三种模式对比
-
代码复杂度:简单工厂模式 < 工厂方法模式 < 抽象工厂模式
-
结构复杂度:简单工厂模式 < 工厂方法模式 < 抽象工厂模式
-
编程复杂度:简单工厂模式 < 工厂方法模式 < 抽象工厂模式
-
管理复杂度:简单工厂模式 < 工厂方法模式 < 抽象工厂模式
-
-
根据设计原则,应使用工厂方法模式
根据实际业务,工厂方法模式使用最多
-
工厂模式应用场景:
-
JDK中的Calenda的getInstance()方法
-
JDBC中的Connection对象的获取
-
Spring中IOC容器创建管理bean对象
-
-