前言
工厂模式的设计目的是将创建对象的操作封装到工厂类中,实现实例化对象与主项目依赖关系的解耦,达到提高代码的可扩展性及维护性的目的。工厂模式有分为三种实现思路,分别是简单工厂模式、工厂方法模式、抽象工厂模式,本文将通过案例分析,对这三种工厂模式进行详解讲解。
一、简单(静态)工厂模式
1. 简介
简单工厂模式就是直接创建一个类,由该类负责所有相关对象的实例化操作。 简单工厂中的方法一般都设计为静态方法,因此又称为静态工厂模式。
2. 案例实现
- 案例介绍
请完成生产各类汽车的项目需求。 - 简单工厂模式类图设计
设计一个CarFactory工厂类,负责相关汽车的生产(对象实例化)。
- 代码实现
public interface ICar {
public void name();
}
public class xiaopeng implements ICar {
@Override
public void name() {
System.out.println("小鹏汽车创建完成!");
}
}
public class weilai implements ICar {
@Override
public void name() {
System.out.println("蔚来汽车创建完成!");
}
}
public class lixiang implements ICar {
@Override
public void name() {
System.out.println("理想汽车创建完成!");
}
}
//设计简单工厂类完成汽车的创建操作
public class CarFactory {
public static ICar CreateCar(String car)
{
if (car.equals("小鹏"))
{
return new xiaopeng();
}
else if (car.equals("蔚来"))
{
return new weilai();
}
else if (car.equals("理想"))
{
return new lixiang();
}
else
return null;
}
}
public class Consumer {
public static void main(String[] args) {
//使用简单工厂模式实例化对象
Car car0 = CarFactory.CreateCar("小鹏");
Car car1 = CarFactory.CreateCar("理想");
car0.name();
car1.name();
}
}
- 优缺点分析
优点:代码思路简单
缺点:不满足开闭原则。如果新增一种汽车类型,就要修改已有的工厂类。
针对简单工厂模式存在的确实,又提出了工厂方法模式,该模式满足开闭原则。
二、工厂方法模式
1. 简介
工厂方法模式不是直接由工厂类负责对象的实例化,而是将对象的实例化推迟到子类中实现,即定义一个创建对象的抽象方法,由子类决定要实例化的类。 这样设计就可以解决简单工厂模式违反开闭原则的问题。
2. 案例实现
-
案例介绍
与简单工厂模式的案例需求一样,仍然是完成生产各类汽车的项目。 -
工厂方法模式类图设计
设计一个工厂接口,然后具体的工厂类推迟到子类去实现。
-
代码实现
public interface ICar {
public void name();
}
public class xiaopeng implements ICar {
@Override
public void name() {
System.out.println("小鹏汽车创建完成!");
}
}
public class weilai implements ICar {
@Override
public void name() {
System.out.println("蔚来汽车创建完成!");
}
}
public class lixiang implements ICar {
@Override
public void name() {
System.out.println("理想汽车创建完成!");
}
}
//工厂抽象类
public abstract CarFactory {
//抽象方法
public abstract ICar CreateCar();
}
public class xiaopengFactory extends CarFactory {
@Override
public ICar CreateCar() {
return new xiaopeng();
}
}
public class weilaiFactory extends CarFactory {
@Override
public ICar CreateCar() {
return new weilai();
}
}
public class lixiangFactory extends CarFactory {
@Override
public ICar CreateCar() {
return new lixiang();
}
}
//消费端(客户端)
public class Consumer {
public static void main(String[] args) {
ICar car0 = new xiaopengFactory().CreateCar();
ICar car1 = new weilaFactory().CreateCar();
car0.name();
car1.name();
}
}
- 优缺点分析
优点:满足工厂模式的要求(创建对象与客户端解耦),同时遵守开闭原则
缺点:编写的类较多,比较复杂。
大多数情况下都是直接使用简单工厂模式
三、抽象工厂模式
1. 简介
抽象工厂模式是定义一个接口负责创建相关或有依赖关系的对象簇,具体实现由工厂子类完成。
抽象工厂模式是简单工厂模式与工厂方法模式的整合,它将工厂抽象为两层,一层定义相关对象创建的抽象工厂,一层是具体实现的工厂子类。
抽象工厂可以理解为是产生工厂的工厂。
2. 案例实现
-
案例介绍
实现不同手机厂商相关产品的生成项目。 -
抽象工厂模式类图设计
设计一个抽象工厂类IProductFactory,然后具体的工厂类由子类去实现。
-
代码实现
//手机产品接口
public interface IPhoneProduct {
void start();
void shutdown();
void sendMeg();
void callUp();
}
public class HuaweiPhone implements IPhoneProduct {
@Override
public void start() {
System.out.println("华为手机开机");
}
@Override
public void shutdown() {
System.out.println("华为手机关机");
}
@Override
public void sendMeg() {
System.out.println("华为手机发短信");
}
@Override
public void callUp() {
System.out.println("华为手机打电话");
}
}
public class XiaomiPhone implements IPhoneProduct {
@Override
public void start() {
System.out.println("小米手机开机");
}
@Override
public void shutdown() {
System.out.println("小米手机关机");
}
@Override
public void sendMeg() {
System.out.println("小米手机发短信");
}
@Override
public void callUp() {
System.out.println("小米手机打电话");
}
}
//路由器产品接口
public interface IRouterProduct {
void start();
void shutdown();
void openWifi();
void setting();
}
public class HuaweiRouter implements IRouterProduct {
@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("华为路由器设置");
}
}
public class XiaomiRouter implements IRouterProduct {
@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("小米路由器设置");
}
}
//抽象产品工厂(核心),适合应用于产品系列比较稳定的时候,因为如果加新的产品,那么大量的代码要添加和改动
public interface IProductFactory {
//生产手机
IPhoneProduct phone();
//生产路由器
IRouterProduct router();
}
public class HuaweiFactory implements IProductFactory{
@Override
public IPhoneProduct phone() {
return new HuaweiPhone();
}
@Override
public IRouterProduct router() {
return new HuaweiRouter();
}
}
public class XiaomiFactory implements IProductFactory{
@Override
public IPhoneProduct phone() {
return new XiaomiPhone();
}
@Override
public IRouterProduct router() {
return new XiaomiRouter();
}
}
//使用端
public class Consumer{
public static void main(String[] args) {
System.out.println("=============小米系列产品=============");
XiaomiFactory xiaomiFactory = new XiaomiFactory();
IPhoneProduct xiaomiPhone = xiaomiFactory.phone();
xiaomiPhone.start();
xiaomiPhone.callUp();
xiaomiPhone.shutdown();
IRouterProduct xiaomirouter = xiaomiFactory.router();
xiaomirouter.start();
xiaomirouter.openWifi();
xiaomirouter.shutdown();
System.out.println("=============华为系列产品=============");
HuaweiFactory huaweiFactory = new HuaweiFactory();
IPhoneProduct huaweiPhone = huaweiFactory.phone();
huaweiPhone.start();
huaweiPhone.callUp();
huaweiPhone.shutdown();
IRouterProduct huaweirouter = huaweiFactory.router();
huaweirouter.start();
huaweirouter.setting();
huaweirouter.shutdown();
}
}
- 优缺点分析
优点:具体产品创建与应用层的代码隔离,无需关心创建的细节;将一个系列的产品统一到一起创建。
缺点:规定了所有可能被创建的产品集合。产品簇中扩展新的产品困难;增加了系统的抽象性和理解难度。