工厂模式
每天一篇系列:
强化知识体系,查漏补缺。
欢迎指正,共同学习!
工厂模式主要是为创建对象提供了接口。
按照《Java与模式》中的提法分为三类:
- 工厂方法模式(Factory Method)
- 抽象工厂模式(Abstract Factory)
使用工厂模式的两种情况:
1.编码时不清楚要使用哪种实例
结合自己在项目上经验来看,MediaPlayerFactory工厂类就是根据播放协议来确定底层播放器(比如本地文件、http、rtsp的区分)
2.系统不应依赖于产品类实例如何被创建、组合和表达的细节
这种并不能很好的理解,在项目上也不太能匹配上
1.工厂方法模式
由四个角色组成:
1.抽象工厂类
根据不同业务可以创建不同的具体产品
2.具体工厂类
继承抽象工厂类常见一个具体产品类实例
3.抽象产品类
提取产品抽象特性,供具体产品类继承实现多态
4.具体产品类
继承抽象产品类,实现具体业务
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
网上有一个例子说的很好,一个客户需要车:
public class BMW320 {
public BMW320(){
System.out.println("制造-->BMW320");
}
}
public class BMW523 {
public BMW523(){
System.out.println("制造-->BMW523");
}
}
public class Customer {
public static void main(String[] args) {
BMW320 bmw320 = new BMW320();
BMW523 bmw523 = new BMW523();
}
}
![](https://img.haomeiwen.com/i3613947/bf9c14551f06111e.png)
这里客户自己来生产对应型号的车,客户和车就联系在一起了,为了降耦合,可以使用工厂方法模式:
![](https://img.haomeiwen.com/i3613947/55cce67e8af8fa61.png)
//抽象产品类
abstract class BMW {
public BMW(){
}
}
//具体产品类
public class BMW320 extends BMW {
public BMW320() {
System.out.println("制造-->BMW320");
}
}
//具体产品类
public class BMW523 extends BMW{
public BMW523(){
System.out.println("制造-->BMW523");
}
}
//工厂类
public class Factory {
public BMW createBMW(int type) {
switch (type) {
case 320:
return new BMW320();
case 523:
return new BMW523();
default:
break;
}
return null;
}
}
//客户类
public class Customer {
public static void main(String[] args) {
Factory factory = new Factory();
BMW bmw320 = factory.createBMW(320);
BMW bmw523 = factory.createBMW(523);
}
}
这里客户只需要告诉生产车的型号,工厂就可以开始生产这个型号的车,已经完成了客户和产品的解耦,生产交给工厂处理。这里只是最简单的工厂方法模式,可以看到一个工厂要生产各种型号的车,业务需求多了工厂就越来越大,实际上应该分成各个小工厂来生产固定型号的车。看看工厂方法模式如下:
//抽象产品类
abstract class BMW {
public BMW(){
}
}
//具体产品类
public class BMW320 extends BMW {
public BMW320() {
System.out.println("制造-->BMW320");
}
}
//具体产品类
public class BMW523 extends BMW{
public BMW523(){
System.out.println("制造-->BMW523");
}
}
//工厂类
interface FactoryBMW {
BMW createBMW();
}
public class FactoryBMW320 implements FactoryBMW{
@Override
public BMW320 createBMW() {
return new BMW320();
}
}
public class FactoryBMW523 implements FactoryBMW {
@Override
public BMW523 createBMW() {
return new BMW523();
}
}
//客户类
public class Customer {
public static void main(String[] args) {
FactoryBMW320 factoryBMW320 = new FactoryBMW320();
BMW320 bmw320 = factoryBMW320.createBMW();
FactoryBMW523 factoryBMW523 = new FactoryBMW523();
BMW523 bmw523 = factoryBMW523.createBMW();
}
}
从上面可以看到比简单工厂方法模式灵活的是,可以要去根据不同型号生产需求去告诉对应工厂生产,也就是把工厂封装成各种小工厂。工厂方法模式仿佛已经很完美的对对象的创建进行了包装,使得客户程序中仅仅处理抽象产品角色提供的接口,但使得对象的数量成倍增长。当产品种类非常多时,会出现大量的与之对应的工厂对象,这不是我们所希望的。
抽象工厂模式
//发动机以及型号
public interface Engine {
}
public class EngineA extends Engine{
public EngineA(){
System.out.println("制造-->EngineA");
}
}
public class EngineBextends Engine{
public EngineB(){
System.out.println("制造-->EngineB");
}
}
//空调以及型号
public interface Aircondition {
}
public class AirconditionA extends Aircondition{
public AirconditionA(){
System.out.println("制造-->AirconditionA");
}
}
public class AirconditionB extends Aircondition{
public AirconditionB(){
System.out.println("制造-->AirconditionB");
}
}
//创建工厂的接口
public interface AbstractFactory {
//制造发动机
public Engine createEngine();
//制造空调
public Aircondition createAircondition();
}
//为宝马320系列生产配件
public class FactoryBMW320 implements AbstractFactory{
@Override
public Engine createEngine() {
return new EngineA();
}
@Override
public Aircondition createAircondition() {
return new AirconditionA();
}
}
//宝马523系列
public class FactoryBMW523 implements AbstractFactory {
@Override
public Engine createEngine() {
return new EngineB();
}
@Override
public Aircondition createAircondition() {
return new AirconditionB();
}
}
public class Customer {
public static void main(String[] args){
//生产宝马320系列配件
FactoryBMW320 factoryBMW320 = new FactoryBMW320();
factoryBMW320.createEngine();
factoryBMW320.createAircondition();
//生产宝马523系列配件
FactoryBMW523 factoryBMW523 = new FactoryBMW523();
factoryBMW523.createEngine();
factoryBMW523.createAircondition();
}
}
看起来和工厂方法模式很像,按照定义工厂模式方法生产多个配件就需要多个工厂,而抽象工厂只需要一个工厂。
在使用时,我们不必去在意这个模式到底工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。经常你会发现,明明使用的工厂方法模式,当新需求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了;而对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。所以,在使用工厂模式时,只需要关心降低耦合度的目的是否达到了