参考链接:http://www.runoob.com/design-pattern/abstract-factory-pattern.html
示例代码:https://github.com/jianghan0712/design-pattern
目录
简单工厂
一、综述
非常常用的创造型模式,在Java中随处可见,与反射结合起来用最好了。现实中,如log4j,logpack等便提供了slf4j需要的工厂方法,所以可以方便的构造自己的系统。另一个好处是,创建过程中,可以不对客户端暴露自己的创建逻辑。
二、主要思想
Factory工厂类提供统一的调用接口,具体实现在各子类中实现。使用反射机制,传给Factory你想要创建对象的Class,工厂最后返回给你实际的对象
三、示例UML
(原图地址:www.runoob.com/design-pattern/factory-pattern.html)
四、示例代码
在这个系统中,存在3种角色,要屏蔽Product和User之间的耦合关系
Product:实际的产品
Factory:工厂类
User:实际产品的使用者
统一的产品定义接口
Sharp.java
public interface Shape {
void draw();
}
两个实际的产品:
Rectangle.java
public class Rectangle implements Shape{
@Override
public void draw() {
// TODO Auto-generated method stub
System.out.println("this is a rectangle");
}
}
Square.java
public class Square implements Shape{
@Override
public void draw() {
// TODO Auto-generated method stub
System.out.println("this is a square");
}
}
工厂类SharpFactory.java
public class SharpFactory {
//用反射机制实现,创建基于该类的一系列对象。在本例中并无效果,但在实际中非常常见
public static Object getShape(Class<?> c1) {
Object en = null;
try {
en = c1.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return en;
}
//普通方法实现
public static Shape getShape(String type) {
Shape ret = null;
if(type.equalsIgnoreCase("square")) {
ret = new Square();
}else if(type.equalsIgnoreCase("rectangle")){
ret = new Rectangle();
}
return ret;
}
}
测试类,分别用两种方法创建对象
Main.java
public class Main {
public static void main(String[] args) {
System.out.println("use reflect");
Square test = (Square)SharpFactory.getShape(Square.class);
test.draw();
System.out.println("----------------------");
System.out.println("use commom");
Square test2 = (Square)SharpFactory.getShape("Square");
test2.draw();
}
}
五、总结
适用场景:需要工厂管理的类比较少。如果过多时,会非常难以维护
抽象工厂
一、综述
通常,一个具体的工厂生产一个具体的产品,但有时我们需要一个工厂能够提供多个产品对象,此时,要使用抽象工厂
二、主要思想
客户端调用的工厂类,实质是多个具体工厂的集合,所以又被称为工厂的工厂。比如示例中,有两个产品族:形状和颜色。提供两种形状:Square和Rectangle,两种颜色:Yellow和Red。也就是有四种对应的工厂方法。但客户端并不直接调用,而是通过另一个工厂类FactoryProducer来统一生产。比如,要求生产红色的正方形,则传入参数red和square,工厂便会调用对应产品的工厂类来生产所需的东西。
三、示例UML
四、示例代码
两个产品族color和shape;两个产品族的工厂类ColorFactory和ShapeFactory; color下的两个实现类Yellow和red;Shape下的两个实现类Square和Rectangle;一个超级工厂 FactoryProducer;一个测试类Main
两个产品族接口定义
Color.java
public interface Color {
void fill();
}
Sharp.java
public interface Shape {
void draw();
}
分别定义两个实体类
color的两个实体
Red.java
public class Red implements Color{
@Override
public void fill() {
// TODO Auto-generated method stub
System.out.println("Red:fill() method");
}
}
Yellow.java
public class Yellow implements Color{
@Override
public void fill() {
// TODO Auto-generated method stub
System.out.println("Yellow:fill() method");
}
}
两个产品族分别的工厂方法
ShapeFactory.java
public class ShapeFactory extends AbstractFactory{
@Override
public Object getColor(Class<?> color) {
// TODO Auto-generated method stub
return null;
}
@Override
public Object getShape(Class<?> shape) {
// TODO Auto-generated method stub
Object en = null;
try {
en = shape.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return en;
}
}
ColorFactory.java
public class ColorFactory extends AbstractFactory{
@Override
public Object getColor(Class<?> color) {
// TODO Auto-generated method stub
Object en = null;
try {
en = color.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return en;
}
@Override
public Object getShape(Class<?> shape) {
return null;
}
}
最后,创建两个工厂方法的超级工厂FactoryProducer.java
public class FactoryProducer {
public static AbstractFactory getFactory(String choice){
if(choice.equalsIgnoreCase("SHAPE")){
return new ShapeFactory();
} else if(choice.equalsIgnoreCase("COLOR")){
return new ColorFactory();
}
return null;
}
}
测试类Main.java
public class Main {
public static void main(String[] args) {
//获取形状工厂
AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
//获取形状为 Circle 的对象
Shape shape1 = (Square)shapeFactory.getShape(Square.class);
//调用 Circle 的 draw 方法
shape1.draw();
//获取形状为 Rectangle 的对象
Shape shape2 = (Rectangle)shapeFactory.getShape(Rectangle.class);
//调用 Rectangle 的 draw 方法
shape2.draw();
//获取颜色工厂
AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
//获取颜色为 Red 的对象
Color color1 = (Red)colorFactory.getColor(Red.class);
//调用 Red 的 fill 方法
color1.fill();
//获取颜色为 Green 的对象
Color color2 = (Yellow)colorFactory.getColor(Yellow.class);
//调用 Green 的 fill 方法
color2.fill();
}
}
五、总结
适用场景:1. 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是重要的。
2.系统中有多于一个的产品族,而每次只使用其中某一产品族。
3. 属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。
4. 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象
缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。