工厂模式作为建造类型模式的一种,工厂顾名思义就是创建产品,根据产品是具体产品还是具体工厂可分为简单工厂模式和工厂方法模式,根据工厂的抽象程度可分为工厂方法模式和抽象工厂模式。该模式用于封装和管理对象的创建,是一种创建型模式。本文从一个具体的例子逐步深入分析,来体会三种工厂模式的应用场景和利弊。
1. 简单工厂模式
简单工厂由名称就知道最为简单,其只对具体的产品做一层很薄的封装,根据指定的类型来创建对象,idea画出的UML类型:
手机接口规范:
package com.patten.factory;
public interface Phone {
void desc();
}
实现厂商:
package com.patten.factory.product;
import com.patten.factory.Phone;
public class IPhone implements Phone {
public IPhone() {
this.desc();
}
@Override
public void desc() {
System.out.println("苹果手机制造成功!");
}
}
package com.patten.factory.product;
import com.patten.factory.Phone;
public class MiPhone implements Phone {
public MiPhone() {
this.desc();
}
@Override
public void desc() {
System.out.println("小米手机制造成功!");
}
}
简单工厂:
public class PhoneSimpleFactory {
public static Phone makePhone(String phoneName) {
if ("xiaomi".equalsIgnoreCase(phoneName)) {
return new MiPhone();
} else if ("iphone".equalsIgnoreCase(phoneName)) {
return new IPhone();
}
throw new RuntimeException("工厂暂时生成不了该类型手机!");
}
}
客户端:
public class SimpleFacClient {
public static void main(String[] args) {
//简单工厂
Phone xiaomi = PhoneSimpleFactory.makePhone("xiaomi");
Phone iphone = PhoneSimpleFactory.makePhone("iphone");
}
}
2. 工厂方法模式(Factory Method)
工厂方法就不在想简单工厂一样直接面对具体的产品,而是面对具体的工厂,在产品种类单一的情况下我们称之为工厂方法模式。
class依赖图:
工厂规范:
public abstract class AbstractPhoneFactory {
//生产手机工厂
abstract Phone createPhone();
}
具体的工厂实现:
public class IPhoneFactory extends AbstractPhoneFactory {
@Override
public Phone createPhone() {
return new IPhone();
}
}
public class MiPhoneFactory extends AbstractPhoneFactory {
@Override
public Phone createPhone() {
return new MiPhone();
}
}
客户端示例:
public class Demo {
public static void main(String[] args) {
//根据不同的工厂制造手机
MiPhoneFactory xiaomiFac = new MiPhoneFactory();
IPhoneFactory iphoneFac = new IPhoneFactory();
xiaomiFac.createPhone();
iphoneFac.createPhone();
}
}
3.抽象工厂模式
工厂旨在创建生产对象,对于工厂方法模式,生产的都是单一的产品,但是若我们想再生产另一件产品,例如我们已经有手机工厂方法,但是我们此时又想生产耳机,按照工厂方法的方式,那么我们需要再新建抽象类,新的实现,这虽然满足单一职责原则,但是也使类过多,在分析单一职责原则的时候,我们也可以用在方法层面的单一职责。
因此我们可以采用复用原则,在抽象工厂中新增生产耳机的方法。这样每个工厂又可以生产手机和耳机。
UML图:
新增耳机产品:
public interface Headset {
void desc();
}
苹果耳机:
public class IHeadset implements Headset {
public IHeadset() {
this.desc();
}
public void desc() {
System.out.println("生产苹果耳机!");
}
}
小米耳机:
public class MiHeadset implements Headset {
public MiHeadset() {
this.desc();
}
public void desc() {
System.out.println("生产小米耳机!");
}
}
抽象工厂规范:
public abstract class AbstractPhoneFactory {
//生产手机工厂
abstract Phone createPhone();
//生产耳机
Headset createHeadset(){
throw new RuntimeExcetion("不支持的产品");
}
}
苹果工厂:
public class IPhoneFactory extends AbstractPhoneFactory {
@Override
public Phone createPhone() {
return new IPhone();
}
@Override
Headset createHeadset() {
return new IHeadset();
}
}
小米工厂:
public class MiPhoneFactory extends AbstractPhoneFactory {
@Override
public Phone createPhone() {
return new MiPhone();
}
@Override
Headset createHeadset() {
return new MiHeadset();
}
}
示例:
public class Demo {
public static void main(String[] args) {
//根据不同的工厂制造手机
MiPhoneFactory xiaomiFac = new MiPhoneFactory();
IPhoneFactory iphoneFac = new IPhoneFactory();
xiaomiFac.createPhone();
iphoneFac.createPhone();
//耳机
Headset mi = xiaomiFac.createHeadset();
Headset iphoneFacHeadset = iphoneFac.createHeadset();
}
}
小结
1) 工厂模式的意义
将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的 依赖关系的解耦。从而提高项目的扩展和维护性。
2) 三种工厂模式 (
简单工厂模式、工厂方法模式、抽象工厂模式
)
3) 设计模式的依赖抽象
原则
创建对象实例时,不要直接 new
类
,
而是把这个
new
类的动作放在一个工厂的方法 中,并返回。有的书上说,变量不要直接持有具体类的引用。
不要让类继承具体类,而是继承抽象类或者是实现interface(
接口
)
不要覆盖基类中已经实现的方法