16
07月
JAVA设计模式(二):抽象工程模式(Abstract Factory Pattern)
抽象工厂模式属于创建模式,它提供一个创建一系列或相互依赖对象的接口,而无须指定他们具体的类。系统设计时,为了解耦和便于系统维护,通常不希望用户直接使用new运算符实例化所需要的一系列相关的对象,而是由系统来控制这些对象的创建。
抽象工厂模式属于创建模式,它提供一个创建一系列或相互依赖对象的接口,而无须指定他们具体的类。系统设计时,为了解耦和便于系统维护,通常不希望用户直接使用new运算符实例化所需要的一系列相关的对象,而是由系统来控制这些对象的创建,在这种情况下,抽象工厂设计模式是一个很好的选择。抽象工厂模式的关键在于一个接口(或者抽象类),它里面定义了若干个抽象方法,这些抽象方法分别用来创建某个特定类的实例,它的子类(或者实现类)必须重写这些方法,为用户提供一系列相关的对象。
抽象工厂模式的结构中包括了四种角色:
抽象产品(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就好了,而不用去更改现有的代码,这种可以灵活扩展的设计方式符合开闭原则(一个软件实体如类、模块和函数应该对扩展开放,对修改关闭,此原则为设计模式的总纲)。
这样创新的模式,值得你的选择!
蜗牛学院,只为成就更好的你!
还在等什么,赶快关注蜗牛学院官方微信,加入到蜗牛学院的大家庭中来吧!

版权所有,转载本站文章请注明出处:蜗牛学苑,
https://www.woniuxy.cn/article/28