原文地址为https://cloud.tencent.com/developer/article/1557495,转载请注明出处!
工厂模式
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
简单工厂模式
简介
简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫静态工厂方法模式(Static FactoryMethod Pattern),是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
将“类实例化的操作”与“使用对象的操作”分开,让使用者不用知道具体参数就可以实例化出所需要的“产品”类,从而避免了在客户端代码中显式指定,实现了解耦。
即使用者可直接消费产品而不需要知道其生产的细节
优缺点
优点:实现解耦,不用关注如何生产,将使用和生产分离,如果生产的产品只有一种这种方式可以满足使用。
缺点:如果新增产品,例如新增vivo手机,需要在SimpleFac
中修改源码,不符合设计模式的开闭原则——对修改关闭,对扩展开放
,因此简单工厂模式不属于23种设计模式中的一种。
示例
我们通过手机的生产过程来演示简单工厂模式。
手机产品的接口及其实现类
代码语言:javascript复制/**
* 手机接口
*/
public interface Phone {
/** 打电话 */
void call();
}
public class Iphone implements Phone{
@Override
public void call() {
System.out.println("iphone拨打电话");
}
}
public class Xiaomi8 implements Phone {
@Override
public void call() {
System.out.println("小米8拨打电话");
}
}
用来表示手机名称的枚举类
代码语言:javascript复制/**
* 手机名称 enum
*/
public enum PhoneNameEnum {
/** iphone */
IPHONE11("iphone"),
/** 小米8 */
XIAOMI8("xiaomi8"),
;
String name;
PhoneNameEnum(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
生产手机产品的工厂类
代码语言:javascript复制public class SimplePhoneFac {
public Phone producePhone(String phoneName) {
if (null == phoneName || 0 == phoneName.length()) {
return null;
}
if (phoneName.equals(PhoneNameEnum.IPHONE11.getName())) {
return new Iphone();
} else if (phoneName.equals(PhoneNameEnum.XIAOMI8.getName())) {
return new Xiaomi8();
} else {
return null;
}
}
}
测试结果
代码语言:javascript复制public class SimpleFacTest {
public static void main(String[] args) {
SimplePhoneFac simplePhoneFac = new SimplePhoneFac();
Iphone iphone = (Iphone) simplePhoneFac.producePhone(PhoneNameEnum.IPHONE11.getName());
if (null == iphone) {
System.out.println("iphone 生产失败");
} else {
iphone.call();
}
Xiaomi8 xiaomi8 = (Xiaomi8) simplePhoneFac.producePhone(PhoneNameEnum.XIAOMI8.getName());
if (null == xiaomi8) {
System.out.println("xiaomi8 生产失败");
} else {
xiaomi8.call();
}
}
}
代码语言:javascript复制iphone拨打电话
小米8拨打电话
工厂方法模式
简介
工厂方法模式,又称工厂模式,定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。这满足创建型模式中所要求的“创建与使用相分离”的特点。
将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化(创建)哪一个类。
本节介绍的工厂方法模式是对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则。
模式的结构
工厂方法模式的主要角色如下。
- 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct() 来创建产品。
- 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
- 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
- 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
优缺点
工厂方法模式的主要优点有:
- 用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;
- 在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;
其缺点是:每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。
示例
我们通过手机工厂分别生成iphone和小米8两种机型来说明工厂方法模式。后续如果新增产品例如Vivo手机只需要实现Phone接口,创建VivoFac工厂类进行生产即可。
手机产品接口及其具体实现类
代码语言:javascript复制/**
* 手机接口
*/
public interface Phone {
/** 打电话 */
void call();
}
public class Iphone implements Phone{
@Override
public void call() {
System.out.println("iphone拨打电话");
}
}
public class Xiaomi8 implements Phone {
@Override
public void call() {
System.out.println("小米8拨打电话");
}
}
抽象工厂及其具体工厂
代码语言:javascript复制/**
* phone 的抽象工厂
*/
public abstract class AbstractPhoneFac {
/** 生产 phone */
public abstract Phone producePhone();
}
/**
* iphone 生产工厂
*/
public class IphoneFac extends AbstractPhoneFac {
@Override
public Phone producePhone() {
return new Iphone();
}
}
/**
* 小米生产工厂
*/
public class XiaomiFac extends AbstractPhoneFac {
@Override
public Phone producePhone() {
return new Xiaomi8();
}
}
测试结果
代码语言:javascript复制public class FacMethodTest {
public static void main(String[] args) {
XiaomiFac xiaomiFac = new XiaomiFac();
Xiaomi8 xiaomi8 = (Xiaomi8) xiaomiFac.producePhone();
xiaomi8.call();
IphoneFac iphoneFac = new IphoneFac();
Iphone iphone = (Iphone) iphoneFac.producePhone();
iphone.call();
}
}
代码语言:javascript复制小米8拨打电话
iphone拨打电话