1.定义
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象
简单来说:工厂模式就是定义一个用于创建对象的接口,让子类决定实例化哪一个类。
2.概述
得到一个类的子类的实例最常用的办法就是使用new运算符和该类的构造方法,但是在某些情况下,用户可能不应该或者无法使用这种办法来得到一个子类的实例,其原因是系统不予许用户代码和该类的子类形成耦合或者用户不知道该类有哪些子类可以用。比如,有一个PenCore类(笔芯),该类是一个抽象类。假设PenCore类有三个子类,分别是RedPenCore(红笔芯),BluePenCore(蓝笔芯)和BlackPenCore(黑笔芯),而系统设计的目的是为用户提供BallPen(圆珠笔)的子类的实例,即含有笔芯的圆珠笔,也就是说系统想让用户使用BallPen类的子类的实例来得到PenCore类的子类的实例。
具体是的实现看文章后面结构的描述!
3.应用场景
1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。
3、设计一个连接服务器的框架,需要三个协议,“POP3”、“IMAP”、“HTTP”,可以把这三个作为产品类,共同实现一个接口。
4.模式的结构与使用
工厂模式的结构中一般包括四种角色:
1.抽象产品(Product):抽象类或接口,负责定义具体产品必须实现的方法!
2.具体产品(ConcreteProduct):具体产品是一个类,如果Product是一个抽象类,那么具体产品是Product的子类;如果Product是一个接口,那么具体产品就是实现Product接口的类。
3.构造者(Creator):一个接口或抽象类。构造者负责定义一个称作工厂方法的抽象方法,该方法返回具体产品类的实例。
4.具体构造者(ConcreteCreator):如果构造者是抽象类,具体构造者是构造者的子类;如果构造者是接口,具体构造者是是实现构造者接口的类。具体构造者重写工厂方法使该方法返回具体产品的实例。
1.工厂方法模式的UML类图
2.工厂模式的顺序图
3.结构的描述
1.抽象产品
概述中所提到的PenCore(笔芯)类是工厂模式中的Product角色,代码如下:
public abstract class PenCore {
protected String color;
public abstract void writeWord(String s);
}
2.具体产品
概述中提到的RedPenCore,BluePenCore和BlackPenCore类是三个具体的产品角色,代码如下所示:
RedPenCore.java
public class RedPenCore extends PenCore{
public RedPenCore() {
color="红色";
}
@Override
public void writeWord(String s) {
System.out.println("写出"+color+"的字:"+s);
}
}
BluePenCore.java
public class BluePenCore extends PenCore{
public BluePenCore() {
color="蓝色";
}
@Override
public void writeWord(String s) {
System.out.println("写出"+color+"的字:"+s);
}
}
BlackPenCore.java
public class BlackPenCore extends PenCore{
public BlackPenCore() {
color="黑色";
}
@Override
public void writeWord(String s) {
System.out.println("写出"+color+"的字:"+s);
}
}
3.构造者
概述中提到的BallPen类是构造者(Creator)角色,代码如下所示
public abstract class BallPen {
public BallPen() {
System.out.println("生产了一只能装有"+getPenCore()+"笔芯的圆珠笔");
}
public abstract PenCore getPenCore();
}
4.具体构造者
概述中提到的RedBallPen,BlueBallPen,BlackBallPen类是具体构造者角色,代码如下所示:
RedBallPen.java
public class RedBallPen extends BallPen{
@Override
public PenCore getPenCore() {
return new RedPenCore();
}
}
BlueBallPen.java
public class BlueBallPen extends BallPen{
@Override
public PenCore getPenCore() {
return new BluePenCore();
}
}
BlackBalPen.java
public class BlackBallPen extends BallPen{
@Override
public PenCore getPenCore() {
return new BlackPenCore();
}
}
5.测试程序
Application.java
public class Application {
public static void main(String[] args) {
PenCore penCore;
BallPen ballPen=new RedBallPen();
penCore= ballPen.getPenCore();
penCore.writeWord("我是一名Java程序员");
ballPen=new BlueBallPen();
penCore=ballPen.getPenCore();
penCore.writeWord("我正在学习SpringBoot");
ballPen=new BlackBallPen();
penCore=ballPen.getPenCore();
penCore.writeWord("未来我还要学习微服务");
}
}
6.测试结果展示
5.工厂模式的优点
1.使用工厂模式可以让用户的代码和某个特定类的子类的代码解耦
2.工厂方法使用用户不必知道它所使用的对象是怎样被创建的,只需要知道该对象有哪些方法即可。