java抽象工厂模式是什么?抽象工厂模式属于创建模式,它提供一个创建一系列或相互依赖对象的接口,而无须指定他们具体的类。系统设计时,为了解耦和便于系统维护,通常不希望用户直接使用new运算符实例化所需要的一系列相关的对象,而是由系统来控制这些对象的创建,在这种情况下,抽象工厂设计模式是一个很好的选择。抽象工厂模式的关键在于一个接口(或者抽象类),它里面定义了若干个抽象方法,这些抽象方法分别用来创建某个特定类的实例,它的子类(或者实现类)必须重写这些方法,为用户提供一系列相关的对象。

springboot 抽象工厂模式无法连接数据源 java抽象工厂模式详解_java简述工厂模式

抽象工厂模式的结构中包括了四种角色:

抽象产品(Product):一个抽象类或者是接口,负责定义具体产品必须实现的方法。

具体产品(ConcreteProduct):具体产品是抽象产品的非抽象子类或者是实现类。

抽象工厂(AbstractFactory):一个接口或者抽象类,负责定义用来创建产品的抽象方法。

具体工厂(ConcreteFactory):是抽象工厂的实现类或者非抽象子,它的方法将返回产品类的实例。如果一个工厂需要创建两种相关联的产品A和B那么,它们的UML类图如下:

现在假设存在这样的场景:在某城市的管辖范围内有李李宁和耐克两家鞋厂,它们各自生成自己品牌鞋子所需要的鞋垫和鞋身,然后出售给商家。这里的李宁和耐克是鞋厂的具体类型,把它们抽象成出来的鞋厂作为一个抽象工厂,那么这个工厂包括两个方法----生产鞋垫和生产鞋身。不管是李宁牌的鞋垫还是耐克的鞋垫,它们都是具体产品需要实现鞋垫接口,而鞋身也是具体产品,需要实现鞋身的接口。下面给出代码实现。

抽象产品:

/**
* 鞋垫的接口
* @author
*
*/
public interface Shoepad {
public int getSize(); //获取鞋垫的尺寸
public void setSize(int size);
}
/**
* 鞋身
* @author
*
*/
public interface Shoes {
public abstract void walk(); // 步行
public int getSize(); //获得鞋子尺寸
public void setSize(int size);
public String getColor(); // 获得鞋子颜色
public void setColor(String color);
public String getName(); // 获得鞋子品牌
public void setName(String name);
}
李宁鞋身:
/**
* 李宁的鞋
* @author
*
*/
public class LiningShoeImpl implements Shoes {
private String name; //鞋子品牌名
private Integer size; // 鞋子尺寸
private String color; // 鞋子颜色
public LiningShoeImpl(){
}
public LiningShoeImpl(String name, int size, String color){
this.name = name;
this.size = size;
this.color = color;
}
/**
* 步行
*/
@Override
public void walk() {
System.out.println("穿着" + this.name + "鞋子步行");
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
李宁的鞋垫:
/**
* 李宁的鞋垫
* @author Vencoln
*
*/
public class LiningShoepadImpl implements Shoepad {
private int size; //鞋垫长度
public LiningShoepadImpl(){
}
public LiningShoepadImpl(int size){
this.size = size;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
}
耐克的鞋垫:
/**
* 耐克的鞋垫
* @author Vencoln
*
*/
public class NikeShoepadImpl implements Shoepad {
private int size; //鞋垫长度
public NikeShoepadImpl(){
}
public NikeShoepadImpl(int size){
this.size = size;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
}
耐克的鞋身:
/**
* 耐克的鞋
* @author Vencoln
*
*/
public class NikeShoeImpl implements Shoes {
private String name; //鞋子品牌名
private Integer size; // 鞋子尺寸
private String color; // 鞋子颜色
public NikeShoeImpl(){
}
public NikeShoeImpl(String name, int size, String color){
this.name = name;
this.size = size;
this.color = color;
}
/**
* 步行
*/
@Override
public void walk() {
System.out.println("穿着" + this.name + "鞋子步行");
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
以上是抽象产品和具体产品部分的代码。下面是抽象工厂和具体工厂部分代码。
/**
* 抽象鞋厂
* @author Vencoln
*
*/
public interface ShoesFactory {
/**
* 生产鞋子
* @param size
* @param color
* @return
*/
public Shoes produceShoe(int size, String color);
/**
* 生产鞋垫
* @param size
* @return
*/
public Shoepad produceShoepad(int size);
}
李宁的鞋厂:
/**
* 李宁品牌的鞋厂
* @author Vencoln
*
*/
public class LiningShoesFactImpl implements ShoesFactory {
@Override
public Shoes produceShoe(int size, String color) {
return new LiningShoeImpl("李宁", size, color);
}
@Override
public Shoepad produceShoepad(int size) {
return new LiningShoepadImpl(size);
}
}
耐克的鞋厂:
/**
* 耐克品牌的鞋厂
* @author Vencoln
*
*/
public class NikeShoesFactImpl implements ShoesFactory {
@Override
public Shoes produceShoe(int size, String color) {
return new NikeShoeImpl("耐克", size, color);
}
@Override
public Shoepad produceShoepad(int size) {
return new NikeShoepadImpl(size);
}
}

(鞋厂部分代码结束)

接下来就到了商家出场。以为商家(对象的用户)要想购买李宁的鞋子,首先他来到李宁的工厂,告诉厂长他需要尺寸42颜色白色的鞋子,然后厂长就让工厂生产相应大小和颜色的鞋身+鞋垫。代码如下:

public class User {
/**
* @param args
*/
public static void main(String[] args) {
// 鞋子信息
int size = 42;
String color = "白色";
ShoesFactory shoesFact = new NikeShoesFactImpl();
Shoepad pad = shoesFact.produceShoepad(size); // 得到鞋垫
Shoes shoes = shoesFact.produceShoe(size, color); // 得到鞋体
shoes.walk();
}
}

从整个结构上看,用户部分使用的工厂和产品都是依赖于抽象的接口而不是具体的类,符合依赖倒置原则(依赖于抽象,而不依赖于具体。不对实现进行编程,这样就降低了客户与实现模块间的耦合)。另外,如果该城市入驻了新的鞋厂,系统中只需要添加一个新的工厂类,让它实现鞋厂接口ShoesFactory就好了,而不用去更改现有的代码,这种可以灵活扩展的设计方式符合开闭原则。