定义
定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类
核心本质:
- 实例化对象不使用new, 用工厂方法代替
- 将选择实现类, 创建对象统一管理和控制. 从而将调用者跟我们的实现类解耦
作用:实现了创建者和调用者的分离
详细分类:
- 简单工厂模式 :用来生产统一等级结构中的任意产品(对于增加新的产品,需要覆盖已有代码)
- 工厂方法模式 :用来生产同一等级结构中的固定产品(支持增加任意产品)
- 抽象工厂模式 :围绕一个超级工厂创建其他工厂, 该超级工厂又称为其他工厂的工厂
优缺点
优点
- 良好的封装性、代码结构清晰
- 扩展性好。如果想增加一个产品,只需扩展一个工厂类即可
- 典型的解耦框架
-
缺点
每增加一个产品,就需要增加一个产品工厂的类,增加了系统的复杂度
使用场景
(1)需要生成对象的地方。
(2)需要灵活的、可扩展的框架。
(3)数据库访问、数据库可能变化时。
应用实例:
———————————————————————————————————————————————————————————————————— //五菱宏光 public class WuLing implements Car { public void name() { System.out.println(“五菱宏光”); } }
车工厂:
```java
public class CarFactory {
//静态工厂模式
//增加一个新的产品如果不修改代码做不到
//方法一
public static Car getCar(String car){
if (car.equals("五菱宏光")){
return new WuLing();
}else if(car.equals("特斯拉")){
return new Tesla();
}else return null;
}
//方法二
public static Car getWuLing(){
return new WuLing();
}
public static Car getTesla(){
return new Tesla();
}
}
消费者按需调用:
public class Consumer {
public static void main(String[] args) {
//接口,所有实现类
Car wuLing = new WuLing();
Car tesla = new Tesla();
wuLing.name();
tesla.name();
wuLing=CarFactory.getCar("五菱宏光");
tesla=CarFactory.getCar("特斯拉");
wuLing.name();
tesla.name();
}
}
2.工厂方法模式
车&车工厂
//车
public interface Car {
void name();
}
--------------------------------------------------------------------
//车工厂CarFactory
public interface CarFactory {
//工厂方法模式
Car getCar();
}
品牌1:特斯拉&特斯拉工厂
public class Tesla implements Car {
public void name() {
System.out.println("特斯拉");
}
}
--------------------------------------------------------------------
public class TeslaFactory implements CarFactory {
public Car getCar() {
return new Tesla();
}
}
品牌2:五菱&五菱工厂
public class WuLing implements Car {
public void name() {
System.out.println("五菱宏光");
}
}
----------------------------------------------------------------
public class WuLingFactory implements CarFactory {
public Car getCar() {
return new WuLing();
}
}
消费者按需调用
public class Consumer {
public static void main(String[] args) {
//接口,所有实现类
Car wuLing = new WuLingFactory().getCar();
Car tesla = new TeslaFactory().getCar();
wuLing.name();
tesla.name();
}
//结构复杂度: simple
//代码复杂度: simple
//编程复杂度: simple
//管理上的复杂度: simple
//根据设计原则:工厂方法模式!
//根据实际业务:简单工厂模式!
}
3.抽象工厂模式
定义了一个接口用于创建相关或有依赖关系的对象族(对象的接口),而无需明确指定具体类
适用场景:
- 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
- 强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量的重复代码
- 提供一个产品类的库,所有的产品以同样的接口出现,从而使得客户端不依赖于具体的实现
优点:
- 具体产品在应用层的代码隔离,无需关心创建的细节
- 将一个系列的产品统一到一起创建
缺点:
- 规定了所有可能被创建的产品集合,产品簇中扩展新的产品困难;
应用实例:
- JDK中Calendar的getInstance方法
- JDBC中的Connection对象的获取
- Spring中IOC容器创建管理bean对象
- 反射中Class对象的newstance方法
实例
**
产品族1:手机(PhoneProduct)
//手机产品接口
public interface PhoneProduct {
void start();
void shutdown();
void call();
void sendMsg();
}
产品族2:路由器(RouterProduct)
//路由器产品接口
public interface RouterProduct {
void start();
void shutdown();
void openWifi();
void setting();
}
产品工厂(总)ProductFactory
//抽象产品工厂,规定好了生成哪些产品族群
public interface ProductFactory {
//生产手机
PhoneProduct phoneProduct();
//生产路由器
RouterProduct routerProduct();
}
不同品牌的手机产品 XiaomiPhone/XuaweiPhone/…
//小米手机
public class XiaomiPhone implements PhoneProduct {
@Override
public void start() {
System.out.println("小米开机");
}
@Override
public void shutdown() {
System.out.println("小米关机");
}
}
-----------------------------------------------------------------------
//华为手机
public class HuaweiPhone implements PhoneProduct {
@Override
public void start() {
System.out.println("华为开机");
}
@Override
public void shutdown() {
System.out.println("华为关机");
}
@Override
public void call();{
System.out.println("华为打电话");
}
}
不同品牌的路由器产品 XiaomiRouter/TP-Link Router/…
//小米路由器
public class XiaomiRouter implements RouterProduct {
@Override
public void start() {
System.out.println("小米开启路由器");
}
@Override
public void shutdown() {
System.out.println("小米关闭路由器");
}
@Override
public void openWifi() {
System.out.println("小米开启Wifi");
}
@Override
public void setting() {
System.out.println("小米设置路由器");
}
}
--------------------------------------------------------------------------------
//TP-Link 路由器
public class TP-LinkRouter implements RouterProduct {
@Override
public void start() {
System.out.println("TP-Link开启路由器");
}
@Override
public void shutdown() {
System.out.println("TP-Link关闭路由器");
}
@Override
public void openWifi() {
System.out.println("TP-Link开启Wifi");
}
@Override
public void setting() {
System.out.println("TP-Link设置路由器");
}
}
小米工厂 XiaomiFactory (继承产品工厂已有的产品线,加工为小米自己品牌的产品)
public class XiaomiFactory implements ProductFactory {
@Override
public PhoneProduct phoneProduct() {
return new XiaomiPhone();
}
@Override
public RouterProduct routerProduct() {
return new XiaomiRouter();
}
}
华为工厂 HuaweiFactory (继承产品工厂已有的产品线,加工为华为自己品牌的产品)
public class HuaweiFactory implements ProductFactory {
@Override
public PhoneProduct phoneProduct() {
return new HuaweiPhone();
}
}
TP-Link 工厂 TP-LinkFactory (继承产品工厂已有的产品线,加工为TP-Link自己品牌的产品)
public class TP-LinkFactory implements ProductFactory {
@Override
public RouterProduct routerProduct() {
return new TP-LinkRouter();
}
}
消费者按需调用
public class Client {
public static void main(String[] args) {
System.out.println("=================小米系列产品==============");
XiaomiFactory xiaomiFactory = new XiaomiFactory();
PhoneProduct phoneProduct = xiaomiFactory.PhoneProduct();
PhoneProduct.start();
RouterProduct routerProduct = xiaomiFactory.RouterProduct();
routerProduct.start();
System.out.println("=================华为系列产品==============");
HuaweiFactory huaweiFactory = new HuaweiFactory();
IPhoneProduct phoneProduct2 = huaweiFactory.PhoneProduct();
phoneProduct.start();
System.out.println("=================TP-Link系列产品==============");
TP-LinkFactory tp-LinkFactory = new TP-LinkFactory();
RouterProduct routerProduct2 = tp-LinkFactory.RouterProduct();
routerProduct2.start();
}
}
运行结果:
=================小米系列产品==============
小米开机
小米开启路由器
=================华为系列产品==============
华为开机
=================TP-Link系列产品==============
TP-Link开启路由器