设计模式-创建型-抽象工厂模式(Abstract Factory)
创建型-抽象工厂模式
工厂方法中,工厂可以生产一类产品,即用工厂类创建所需的对象。
现在假设我们有一个超级工厂,这个超级工厂包含多个小工厂,每个小工厂所生产的产品类型不一样。(这个超级工厂就是一个抽象工厂,它可以生产不同类的产品)
抽象工厂怎样实现呢,下面我们说明一下:
类图:
类图会在后续补上,现在暂时没画
本文引用W3Cschool中的java教程中设计模式,链接地址https://www.w3cschool.cn/java/java-abstract-factory-pattern.html
假设我们现在不止要做创建外形Shape,我们也要创建打印机Printer。
和工厂模式一样,创建外形Shape和他们的实现类:
Shape.java
public interface Shape { void draw(); }
不同类型的外形对象,即Shape接口的实现类
Rectangle.java
public class Rectangle implements Shape { @Override public void draw() { System.out.println("Inside Rectangle::draw() method."); } }
Square.java
public class Square implements Shape { @Override public void draw() { System.out.println("Inside Square::draw() method."); } }
此时,我们再创建打印机Printer和它的实现类
Printer.java
public interface Printer { void print(); }
不同类型的打印机对象,即Printer接口的实现类
PaperPrinter.java
public class PaperPrinter implements Printer{ @Override public void print() { System.out.println("paper"); } }
WebPrinter.java
public class WebPrinter implements Printer { @Override public void print() { System.out.println("web"); } }
ScreenPrinter.java
public class ScreenPrinter implements Printer{ @Override public void print() { System.out.println("screen"); } }
现在我们创建一个超级工厂,最终结果是让他既能生产外形Shape,也能生产打印机Printer。
AbstractFactory.java
public interface AbstractFactory { abstract Printer getPrinter(String type); abstract Shape getShape(String shape) ; }
现在再建设一些小工厂。在编程上,小工厂为超级工厂接口的实现类。
ShapeFactory.java
public class ShapeFactory implements AbstractFactory{ @Override public Shape getShape(String shapeType){ if(shapeType == null){ return null; } if(shapeType.equalsIgnoreCase("RECTANGLE")){ return new Rectangle(); } else if(shapeType.equalsIgnoreCase("SQUARE")){ return new Square(); } return null; } @Override public Printer getPrinter(String type) { return null; } }
PrinterFactory.java
public class PrinterFactory implements AbstractFactory{ @Override public Shape getShape(String shapeType){ return null; } @Override public Printer getPrinter(String type) { if(type == null){ return null; } if(type.equalsIgnoreCase("paper")){ return new PaperPrinter(); } else if(type.equalsIgnoreCase("web")){ return new WebPrinter(); } else if(type.equalsIgnoreCase("Screen")){ return new ScreenPrinter(); } return null; } }
到现在,其实抽象工厂模式已经写完了。
个人的感觉是,所谓设计模式,其实是一种编程习惯。为什么会有这种编程,肯定是编程是进行程序变动时吃过亏,所以有这种习惯。
大家在进行抽象工厂设计时,其实就是一个大工厂(AbstractFactory抽象类),有一些小工厂(AbstractFactory抽象类的具体实现),小工厂进行对象的创建。
至于具体的代码实现,比如说小工厂(AbstractFactory抽象类的具体实现)到底是怎样实现的,其实没有一个绝对的编程方式。
本文中PrinterFactory.java工厂能根据getShape(String shapeType)中传递的shapeType参数,返回对应的实际外形shape的实现(即小工厂生产的外形),但根据getPrinter(String type)方法,都返回空。此时我们根据是外形Shape或者打印机Printer来建设不同的工厂PrinterFactory.java和PrinterFactory.java。其实我们也可以根据其他方式来区分不同的工厂,创建不同的工厂对象。在新创建的工厂中,getShape和getPrinter方法返回的结果也可以都不为空。这个根据需要也可以进行新工厂的创建。甚至于小工厂(如PrinterFactory.java)中根据传入参数,返回不同对象,也可以换成其他方式,如不同方法名称放回不同对象等,本文中就不做过多的描述(理解了就好,写多了,搞得就像这个东西好复杂一样,其实不然)。
至于使用,示例如下:
AbstractFactoryTest.java
public class AbstractFactoryTest { public static void main(String[] args) { //get shape factory AbstractFactory shapeFactory = (AbstractFactory) new ShapeFactory(); //get an object of Shape Circle Shape shape1 = shapeFactory.getShape("SQUARE"); //call draw method of Shape Circle shape1.draw();; //get an object of Shape Rectangle Shape shape2 = shapeFactory.getShape("RECTANGLE"); //call draw method of Shape Rectangle shape2.draw(); //get printer factory AbstractFactory printerFactory = (PrinterFactory) new PrinterFactory(); Printer printer1 = printerFactory.getPrinter("paper"); printer1.print(); Printer printer2 = printerFactory.getPrinter("Web"); printer2.print(); Printer printer3 = printerFactory.getPrinter("Screen"); printer3.print(); } }
运行结果
Inside Square::draw() method.
Inside Rectangle::draw() method.
paper
web
screen
当然,根据面向对象的思维方式,也可以创建一个使用Factory生成器/生产器类,通过传递Shape或Printer等信息来获取工厂。
FactoryProducer.java
public class FactoryProducer { public static AbstractFactory getFactory(String choice){ if(choice.equalsIgnoreCase("SHAPE")){ return new ShapeFactory(); } else if(choice.equalsIgnoreCase("Printer")){ return new PrinterFactory(); } return null; } }
运用时:
AbstractFactoryPackTest.java
public class AbstractFactoryPackTest { public static void main(String[] args) { //get shape factory AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE"); //get an object of Shape Rectangle Shape shape2 = shapeFactory.getShape("RECTANGLE"); //call draw method of Shape Rectangle shape2.draw(); //get an object of Shape Square Shape shape3 = shapeFactory.getShape("SQUARE"); //call draw method of Shape Square shape3.draw(); //get printer factory AbstractFactory printerFactory = FactoryProducer.getFactory("printer"); Printer printer1 = printerFactory.getPrinter("Paper"); printer1.print(); Printer printer2 = printerFactory.getPrinter("Web"); printer2.print(); Printer printer3 = printerFactory.getPrinter("Screen"); printer3.print(); } }
运行结果:
Inside Rectangle::draw() method.
Inside Square::draw() method.
paper
web
screen
从类图看,其实工厂模式和抽象工厂都差不多,不过工厂模式生产一类产品,而抽象工厂模式相当于一个大工厂,可以生产不同类的产品。
就像是解决方案一样,PrinterFactory与ShapeFactory就是两种解决方案;也想游戏里面的套装一样。
缺点:
抽象工厂生产多个产品,比如说抽象工厂可以同时产生四个产品,但是要是再添加一个产品呢,那么没法大工厂就都需要进行该类产品的添加,扩展型就不难么好了。
posted on 2019-05-17 18:22 xingshouzhan 阅读(167) 评论(0) 编辑 收藏 举报