工厂模式
1.简单工厂模式
简单工厂模式概述
- 定义一个工厂类,他可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类
- 在简单工厂模式中用于被创建实例的方法通常为静态(static)方法,因此简单工厂模式又被成为静态工厂方法
简单工厂模式结构
- 结构示意图
- 结构:
- Factory(工厂):核心部分,负责实现创建所有产品的内部逻辑,工厂类可以被外部直接调用,创建所需对象
- Product(抽象类产品):工厂类所创建的所有对象的父类,封装了产品对象的公共方法。
- ConcreteProduct(具体产品):简单工厂模式的实例化对象,实现抽象类中所有抽象方法
简单工厂模式的优缺点和适用环境
- 优点:
- 工厂类包含必要逻辑判断, 可以决定在什么时候创建哪一个产品的实例。客户端可以免除直接创建产品对象的职责
- 客户端无需知道所创建具体产品的类名,只需知道参数即可
- 也可以引入配置文件,在不修改客户端代码的情况下更换和添加新的具体产品类。
- 缺点:
- 工厂类集中了所有产品的创建逻辑,职责过重,一旦异常,整个系统将受影响
- 引入新的工厂类会增加系统中类的个数,增加系统的复杂度和理解难度
- 违背开闭原则,一旦添加新产品不得不修改工厂类的逻辑,会造成工厂逻辑过于复杂
- 简单工厂模式使用了static静态方法,造成工厂角色无法形成基于继承的等级结构。
- 适用环境:
- 工厂类负责创建对的对象比较少,因为不会造成工厂方法中的业务逻辑过于复杂
- 客户端只知道传入工厂类的参数,对如何创建对象不关心
示例代码
- 抽象产品类
/**
* 抽象产品类
*/
public abstract class Product {
public abstract void show();
}
- 具体产品类
/**
* 具体产品A
*/
class ProductA extends Product{
@Override
public void show() {
System.out.println("生产了产品A");
}
}
/**
* 具体产品B
*/
class ProductB extends Product{
@Override
public void show() {
System.out.println("生产了产品B");
}
}
class ProductC extends Product{
@Override
public void show() {
System.out.println("生产了产品C");
}
- 工厂类
/**
* 简单工厂
*/
public class SimpleFactory {
public static Product getProduct(String productName){
switch (productName){
case "A":
return new ProductA();
case "B":
return new ProductB();
case "C":
return new ProductC();
default :
return null;
}
}
}
- 测试
public static void main(String[] args) {
try {
SimpleFactory.getProduct("A").show();
SimpleFactory.getProduct("B").show();
SimpleFactory.getProduct("C").show();
SimpleFactory.getProduct("D").show();
} catch (Exception e) {
System.out.println("没有该产品");
}
}
测试结果
生产了产品A
生产了产品B
生产了产品C
没有该产品
2.工厂方法模式
工厂方法模式概述
- 工厂方法模式,又称工厂模式、多态工厂模式和虚拟构造器模式,通过定义工厂父类负责定义创建对象的公共接口,而子类负责生成具体对象
- 将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化(创建)那个类
工厂方法模式结构
结构:
- 抽象产品(Product): 具体产品的父类, 定义具体产品的公共接口;
- 具体产品(Concrete Product): 由具体工厂来创建,它同具体工厂之间一一对应。
- 抽象工厂( Creator ): 具体工厂的父类 , 描述具体工厂的公共接口
- 具体工厂(Concrete Creator): 实现抽象工厂中的抽象方法,完成具体产品的创建。
工厂方法模式优缺点及适用环境
-
优点:
- 符合开闭原则,新增产品时,只需要增加相应具体产品类和相应具体工厂
- 符合单一职责原则,每个具体工厂类只负责创建对应产品
- 不使用静态工厂方法,可以形成基于继承的等级结构
-
缺点
- 添加新产品时,除了增加新产品类外,还需要提供对应具体工厂类,增加系统开销
-
适用场景
- 创建某些类的对象的逻辑比较复杂, 并且有很多分支条件,而且还可能增加新的条件。
- 一个类不知道它所需要的对象的类
- 一个类通过其子类来指定创建哪个对象。
- 需要封装创建类的对象的逻辑, 使得这些逻辑局部化。
示例代码
- 抽象产品类
/**
* 抽象产品类
*/
public abstract class Product {
public abstract void show();
}
- 具体产品类
/**
* 具体产品A
*/
class ProductA extends Product{
@Override
public void show() {
System.out.println("产品A");
}
}
/**
* 具体产品B
*/
class ProductB extends Product{
@Override
public void show() {
System.out.println("产品B");
}
}
- 抽象工厂类
//抽象工厂类
abstract class Factory{
public abstract Product getProduct();
}
- 具体工厂类
//工厂A类 - 生产A类产品
class FactoryA extends Factory{
@Override
public Product getProduct() {
return new ProductA();
}
}
//工厂B类 - 生产B类产品
class FactoryB extends Factory{
@Override
public Product getProduct() {
return new ProductB();
}
- 测试类
public static void main(String[] args){
//客户要产品A
FactoryA mFactoryA = new FactoryA();
mFactoryA.getProduct().Show();
//客户要产品B
FactoryB mFactoryB = new FactoryB();
mFactoryB.getProduct().Show();
}
测试结果
产品A
产品B
3.抽象工厂模式
抽象工厂模式概述
一种为用户类提供创建一组相关或互相依赖的对象的接口,而且用户类无需指定他们的具体类就能得到同族的不同等级的产品模式结构
产品族:一个品牌下的所有产品, 同一个工厂生产的,位于不同产品等级结构中的一组产品。
产品等级:多个品牌下的同种产品,产品等级结构即产品的继承结构
抽象工厂模式结构
结构:
- 抽象工厂:提供创建多种产品的接口,可以创建多个不同等级的产品
- 具体工厂:实现抽象工厂中多个抽象方法,完成具体产品的创建
- 抽象产品:定义产品规范,抽象工厂模式有多个抽象产品
- 具体产品:由具体工厂来创建,与具体工厂之间是多对一关系。
抽象工厂模式优缺点及适用环境
- 优点:
- 隔离了具体类的生成, 使得客户端并不需要知道什么被创建。
- 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。
- 增加新的产品族很方便,无须修改已有系统,符合开闭原则。 (也有不符合开闭原则的情况)
- 缺点
- 增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了开闭原则。
- 适用场景:
- 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节
- 系统中有多个产品族,但每次只使用其中某一产品族
- 属于同一个产品族的产品将在一起使用, 这一约束必须在系统的设计中体现出来。
- 产品等级结构稳定, 设计完成之后,不会向系统中增加新的产品等级结构或者删除已有的产品等级结构。
示例代码
- 抽象工厂类
/**
* 抽象工厂类
*/
public interface IProductFactory {
//生产手机
IPhoneProduct phoneProduct();
//生成路由器
IRouterProduct routerProduct();
}
- 抽象产品类
/**
* 手机产品抽象接口
*/
public interface IPhoneProduct {
//开机
void start();
//关机
void shutdown();
//打电话
void callup();
//发邮件
void sendSMS();
}
/**
* 路由器产品抽象接口
*/
public interface IRouterProduct {
//开机
void start();
//关机
void shutdown();
//打开wifi
void openwifi();
//设置
void setting();
}
- 具体工厂类
//华为工厂实现类
public class HuaweiFactory implements IProductFactory {
@Override
public IPhoneProduct phoneProduct() {
return new HuaweiPhone();
}
@Override
public IRouterProduct routerProduct() {
return new HuaweiRouter();
}
}
//小米工厂实现类
public class XiaomiFactory implements IProductFactory {
@Override
public IPhoneProduct phoneProduct() {
return new XiaomiPhone();
}
@Override
public IRouterProduct routerProduct() {
return new XiaomiRouter();
}
}
- 具体产品类
//华为手机实现类
public class HuaweiPhone implements IPhoneProduct {
@Override
public void start() {
System.out.println("开启华为手机");
}
@Override
public void shutdown() {
System.out.println("关闭华为手机");
}
@Override
public void callup() {
System.out.println("华为手机打电话");
}
@Override
public void sendSMS() {
System.out.println("华为手机发邮件");
}
}
//华为路由器实现类
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 XiaomiPhone implements IPhoneProduct {
@Override
public void start() {
System.out.println("开启小米手机");
}
@Override
public void shutdown() {
System.out.println("关闭小米手机");
}
@Override
public void callup() {
System.out.println("小米手机打电话");
}
@Override
public void sendSMS() {
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 static void main(String[] args) {
System.out.println("============小米产品============");
//创建小米工厂
IProductFactory xiaomiFactory = new XiaomiFactory();
//生产小米手机
IPhoneProduct xiaomiPhone = xiaomiFactory.phoneProduct();
xiaomiPhone.start();
xiaomiPhone.sendSMS();
//生产小米路由器
IRouterProduct xiaomiRouter = xiaomiFactory.routerProduct();
xiaomiRouter.openwifi();
xiaomiRouter.setting();
System.out.println("============华为产品============");
//创建华为工厂
IProductFactory huaweiFactory = new HuaweiFactory();
//生产华为手机
IPhoneProduct huaweiPhone = huaweiFactory.phoneProduct();
huaweiPhone.start();
huaweiPhone.sendSMS();
//生产华为路由器
IRouterProduct huaweiRouter = huaweiFactory.routerProduct();
huaweiRouter.openwifi();
huaweiRouter.setting();
}
测试结果
============ 小米产品 ============
开启小米手机
小米手机发邮件
打开小米wifi
设置小米路由器
============ 华为产品 ============
开启华为手机
华为手机发邮件
打开华为wifi
设置华为路由器
总结:
简单工厂模式:只有一个实体工厂类;一个实体工厂类生产所有的产品类,工厂根据传入的参数判断具体生产哪个产品给客户。
工厂方法模式:只有一个抽象产品类;一个实体工厂类生产一种产品类,客户需要知道生产该产品的工厂类名称。
抽象工厂模式:有多个抽象产品类;一个实体工厂类可以生产多种产品类,客户可以从一个工厂获得所有想要的产品。