Java工厂模式(3种Java工厂模式案例详解)

Java工厂模式(3种Java工厂模式案例详解)-mikechen

Java设计模式中的提法,Java工厂模式主要分为三类:简单工厂、工厂方法、抽象工厂这三种Java工厂模式@mikechen

一: 简单工厂模式(Simple Factory)

1.简单工厂模式的定义

简单工厂模式(Simple Factory),又被称为”静态工厂方法模式”,它属于类创建型模式,同属于创建型模式的还有(工厂方法模式,抽象工厂模式,单例模式,建造者模式)。

用一个现实生活的例子更容易理解:生活中的工厂是负责生产产品的,同样在设计模式中,简单工厂模式我们可以理解为负责生产对象的一个类,称为“工厂类”。

 

2.简单工厂模式的优缺点

1. 优点

将创建实例的工作与使用实例的工作分开,使用者不必关心类对象如何创建,实现了解耦;

把初始化实例时的工作放到工厂里进行,使代码更容易维护。

 

2. 缺点

工厂类集中了所有实例(产品)的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响;

违背“开放 – 关闭原则”,一旦添加新产品就不得不修改工厂类的逻辑,这样就会造成工厂逻辑过于复杂。

简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成基于继承的等级结构。

 

3.简单工厂模式的结构

Java工厂模式(3种Java工厂模式案例详解)-mikechen

1)工厂类

工厂角色负责实现创建所有实例的内部逻辑。

2)抽象产品

抽象产品角色是所创建的所有对象的父类,负责描述所有实例所共有的公共接口。

3)具体产品

具体产品角色是创建目标,所有创建的对象都充当这个角色的某个具体类的实例。

 

4.简单工厂模式的实现

主要分为三个步骤:

Java工厂模式(3种Java工厂模式案例详解)-mikechen

1.创建抽象产品类

创建抽象产品类的作用:主要是定义具体产品的公共接口

package com.mikechen.java.design.factory.simple;

/**
* 抽象产品
*
* @author mikechen
*/
public abstract  class Product {




    public abstract  void Create();
    
}

2.创建具体产品类

创建具体产品类的作用:继承抽象产品类,定义生产的具体产品

package com.mikechen.java.design.factory.simple;



/**
* 描述类的作用
*
* @author mikechen
*/
public class ConcreteProduct extends Product{




    @Override
    public void Create() {
        System.out.println("生产具体的产品");
    }
}

3.创建工厂类

创建工厂类的作用:通过创建静态方法从而根据传入不同参数创建不同具体产品类的实例。

package com.mikechen.java.design.factory.simple;


/**
* 工厂
*
* @author mikechen
*/
public class Factory {
    public static Product newInstance() {
        return new ConcreteProduct();
    }
}

这里我做了简化,实际的情况可以根据传入的具体产品参数来实现具体的产品即可。

 

二:工厂方法模式(Factory Method)

1.工厂方法模式的定义

工厂方法模式(英语:Factory method pattern),它属于类创建型模式,也被称为多态工厂模式,其定义了一个创建某种产品的接口,但由子类决定要实例化的产品是哪一个,从而把产品的实例化推迟到子类。

在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做,这个核心类则摇身一变,成为了一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触产品类被实例化的细节。

 

2.工厂方法模式的优缺

Java工厂模式(3种Java工厂模式案例详解)-mikechen

1.优点

1)遵循开闭原则

无需更改现有客户端代码,新增一种产品时,只需要增加相应的具体产品类和相应的工厂子类即可,而简单工厂模式需要修改工厂类的判断逻辑。

2)遵循单一职责原则

每个具体工厂类只负责创建对应的产品,而简单工厂中的工厂类存在复杂的switch逻辑判断。

3)不使用静态工厂方法

不使用静态工厂方法,可以形成基于继承的等级结构,简单工厂模式的工厂类使用静态工厂方法。

2.缺点

每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。

 

3.工厂方法模式的结构

工厂方法模式包含如下4类角色:
Java工厂模式(3种Java工厂模式案例详解)-mikechen

1.Product:抽象产品

它是定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的公共父类

2.ConcreteProduct:具体产品

这个角色实现了抽象产品角色所声明的接口,工厂方法模式所创建的每一个对象都是某个具体产品角色的实例。

3.Factory:抽象工厂

抽象工厂是工厂方法模式的核心,所有创建对象的工厂类都必须实现该接口。

4.ConcreteFactory:具体工厂

它是抽象工厂类的子类,实现了抽象工厂中定义的工厂方法,工厂方法模式所创建的每一个对象都是某个具体产品角色的实例。

 

4.工厂方法模式的实现

Java工厂模式(3种Java工厂模式案例详解)-mikechen

1.创建抽象工厂类

创建抽象工厂类的主要作用:定义具体工厂的公共接口。

源码示例如下:

package com.mikechen.java.design.factory.method;

/**
 * 抽象工厂
 *
 * @author mikechen
 */
public abstract  class AbstractFactory {
    public abstract AbstractProduct produceProduct();
}

2.创建抽象产品类

创建抽象产品类的主要作用:定义具体产品的公共接口。

源码示例如下:

package com.mikechen.java.design.factory.method;

/**
 * 抽象产品
 *
 * @author mikechen
 */
public abstract  class AbstractProduct {

    public abstract void make();

}

3.创建具体产品类

创建具体产品类的主要作用:继承抽象产品类,定义生产的具体产品。

1)具体产品A

源码示例如下:

package com.mikechen.java.design.factory.method;

/**
 * 目标产品A
 *
 * @author mikechen
 */
public class ConcreteProductA extends AbstractProduct {

    @Override
    public void make() {
        System.out.println("产品A出炉");
    }
}

2)具体产品B

源码示例如下:

package com.mikechen.java.design.factory.method;

/**
 * 目标产品B
 *
 * @author mikechen
 */
public class ConcreteProductB extends AbstractProduct {

    @Override
    public void make() {
        System.out.println("产品B出炉");
    }
}

4.创建具体工厂类

创建具体工厂类的主要作用:创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法。

源码示例如下:

1)具体工厂A

package com.mikechen.java.design.factory.method;

/**
 * 目标工厂A
 *
 * @author mikechen
 */
public class ConcreteFactoryA extends AbstractFactory {

    @Override
    public AbstractProduct produceProduct() {
       return  new ConcreteProductA();
    }
}

2)具体工厂B

package com.mikechen.java.design.factory.method;

/**
 * 目标工厂B
 *
 * @author mikechen
 */
public class ConcreteFactoryB extends AbstractFactory {
    @Override
    public AbstractProduct produceProduct() {
        return new ConcreteProductB();
    }
}

 

三: 抽象工厂模式(Abstract Factory)

1.抽象工厂模式的定义

抽象工厂(AbstractFactory)模式的定义:是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。

抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品

 

2.抽象工厂模式的优缺点

1.优点:

  • 抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部对产品族进行约束。
  • 增加新的产品族很方便,无需修改已有系统,符合开闭原则。
  • 所谓的产品族,一般或多或少的都存在一定的关联,抽象工厂模式就可以在类内部对产品族的关联关系进行定义和描述,而不必专门引入一个新的类来进行管理。

2.缺点:

  • 增加新的产品等级结构很麻烦,增加新的产品等级结构很麻烦,增加新的产品等级结构很麻烦。
  • 这是因为抽象工厂几乎确定了可以被创建的产品集合,支持新种类的产品就需要扩展该工厂接口,这将涉及抽象工厂类及其所有子类的改变。

 

3.抽象工厂模式的结构

抽象工厂模式包含如下角色:

Java工厂模式(3种Java工厂模式案例详解)-mikechen

1.AbstractFactory:抽象工厂

提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。

2.ConcreteFactory:具体工厂

主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。

3.AbstractProduct:抽象产品

定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。

4.Product:具体产品

实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。

 

4.抽象工厂模式的实现

抽象工厂模式的实现步骤,一般分为如下的5步:

Java工厂模式(3种Java工厂模式案例详解)-mikechen

1.创建抽象工厂类

创建抽象工厂类的主要作用:定义具体工厂的公共接口。

源码示例如下:

package com.mikechen.java.design.factory.abstracts.model;

/**
 * 抽象工厂
 *
 * @author mikechen
 */
public abstract class AbstractFactory {

    //创建A产品家族
    public abstract AbstractProductA createProductA();

    //创建B产品家族
    public abstract AbstractProductB createProductB();

}

2.创建目标工厂

源码示例如下:

1)抽象工厂1

package com.mikechen.java.design.factory.abstracts.model;

/**
 * 目标工厂1
 *
 * @author mikechen
 */
public class ConcreteFactory1 extends AbstractFactory{

    @Override
    public AbstractProductA createProductA() {
        return new ConcreteProductA1();
    }

    @Override
    public AbstractProductB createProductB() {
        return new ConcreteProductB1();
    }
}

 

2)抽象工厂1

package com.mikechen.java.design.factory.abstracts.model;

/**
 * 目标工厂2
 *
 * @author mikechen
 */
public class ConcreteFactory2 extends AbstractFactory{

    @Override
    public AbstractProductA createProductA() {
        return new ConcreteProductA2();
    }

    @Override
    public AbstractProductB createProductB() {
        return  new ConcreteProductB2();
    }
}

 

3.创建抽象产品族类

创建抽象产品族类的,定义抽象产品的公共接口。

1)抽象产品A

源码示例如下:

package com.mikechen.java.design.factory.abstracts.model;

/**
 * 抽象产品A
 *
 * @author mikechen
 */
public abstract class AbstractProductA {

    //每个产品相同方法,不同实现
    public abstract void make();

}

2)抽象产品B

package com.mikechen.java.design.factory.abstracts.model;

/**
 * 抽象产品B
 *
 * @author mikechen
 */
public abstract class AbstractProductB {

    //每个产品相同方法,不同实现
    public abstract void make();

}

4.创建具体产品类

创建具体产品类的主要作用:继承抽象产品类,  定义生产的具体产品。

源码示例如下:

1)目标产品A2

package com.mikechen.java.design.factory.abstracts.model;

/**
 * 目标产品A1
 *
 * @author mikechen
 */
public class ConcreteProductA1 extends AbstractProductA {

    @Override
    public void make() {
        System.out.println("产品A1出炉");
    }
}

2)目标产品A2

package com.mikechen.java.design.factory.abstracts.model;

/**
 * 目标产品A2
 *
 * @author mikechen
 */
public class ConcreteProductA2 extends AbstractProductA {

    @Override
    public void make() {
        System.out.println("产品A2出炉");
    }
}

3)目标产品B1

package com.mikechen.java.design.factory.abstracts.model;

/**
 * 目标产品B1
 *
 * @author mikechen
 */
public class ConcreteProductB1 extends AbstractProductB {

    @Override
    public void make() {
        System.out.println("产品B1出炉");
    }
}

4)目标产品B2

package com.mikechen.java.design.factory.abstracts.model;

/**
 * 目标产品B2
 *
 * @author mikechen
 */
public class ConcreteProductB2 extends AbstractProductB {

    @Override
    public void make() {
        System.out.println("产品B2出炉");
    }
}

 

5.创建具体工厂类

创建具体工厂类的主要作用:继承抽象工厂类,定义创建对应具体产品实例的方法。

源码示例如下:

1)目标工厂1

package com.mikechen.java.design.factory.abstracts.model;

/**
 * 目标工厂1
 *
 * @author mikechen
 */
public class ConcreteFactory1 extends AbstractFactory{

    @Override
    public AbstractProductA createProductA() {
        return new ConcreteProductA1();
    }

    @Override
    public AbstractProductB createProductB() {
        return new ConcreteProductB1();
    }
}

2)目标工厂2

package com.mikechen.java.design.factory.abstracts.model;

/**
 * 目标工厂2
 *
 * @author mikechen
 */
public class ConcreteFactory2 extends AbstractFactory{

    @Override
    public AbstractProductA createProductA() {
        return new ConcreteProductA2();
    }

    @Override
    public AbstractProductB createProductB() {
        return  new ConcreteProductB2();
    }
}

 

作者简介

陈睿|mikechen,10年+大厂架构经验,BAT资深面试官,就职于阿里巴巴、淘宝、百度等一线互联网大厂。

👇阅读更多mikechen架构文章👇

阿里架构 |双11秒杀 |分布式架构 |负载均衡 |单点登录 |微服务 |云原生 |高并发 |架构师

以上

关注作者「mikechen」公众号,获取更多技术干货!

后台回复架构,即可获取《阿里架构师进阶专题全部合集》,后台回复面试即可获取《史上最全阿里Java面试题总结

评论交流
    说说你的看法