工厂模式
实现创建者与调用者的分离
以化妆品为例:
生产者:
一个接口,提供了生产化妆品的方法
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对象
反射中Class对象的newInstance()方法