设计模式之简单工厂、工厂方法、抽象工厂
什么是设计模式?
设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。
简单工厂模式
简单工厂模式(Simple Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的方式。
在简单工厂模式中,包含必要的判断逻辑,简单工厂实现了对象的创建和分离。
在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。
何时使用:
我们明确地计划不同条件下创建不同实例时。
缺点:
(1)工厂类的职责过重,从类图中可以看出简单工厂中包含加减乘除的逻辑判断语句,它一旦有问题,整个系统都要出问题
(2)在添加新的类的时候,例如我添加了开根号运算,那么系统中的简单工厂类就要修改,违反了开放——封闭原则!这样及其不利于系统的扩展和维护!
(3)简单工厂的静态方法,使得工厂角色无法形成基于继承的等级结构!
实例:
画圆形
Shape shape= ShapeFactory.getShape("circle");
shape.draw();
画正方形
Shape shape= ShapeFactory.getShape("rect");
shape.draw();
画三角形
Shape shape= ShapeFactory.getShape("triangle");
shape.draw();
其中,Shape为interface或者抽象类,包括了draw()方法。ShapeFactory(工厂)肯定是一个类,getShape是其静态方法,所以可以直接调用。圆形、正方形、三角形,都是实现了Shape接口/抽象类的对应子类。
工厂
public class ShapeFactory {
public static final String TAG = "ShapeFactory";
public static Shape getShape(String type) {
Shape shape = null;
if (type.equalsIgnoreCase("circle")) {
shape = new CircleShape();
} else if (type.equalsIgnoreCase("rect")) {
shape = new RectShape();
} else if (type.equalsIgnoreCase("triangle")) {
shape = new TriangleShape();
}
return shape;
}
}
工厂方法模式
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
在增加修改新的运算类的时候不用修改代码,只需要增加对应的工厂就好,完全符合开放——封闭性原则。
并且创建对象的细节完全封装在具体的工厂内部,而且有了抽象的工厂类,所有的具体工厂都继承了自己的父类,体现了多态性。
何时使用:
我们明确地计划不同条件下创建不同实例时。
缺点:
(1)在增加新的产品时,也必须增加新的工厂类,会带来额外的开销
(2)抽象层的加入使得理解程度加大
实例:
工厂:
public interface ShapeFactory{
void draw();
}
具体工厂(圆形)
public class CircleFactory implements ShapeFactory{
void draw(){
/*具体实现*/
}
}
具体工厂(正方形)
public class RectFactory implements ShapeFactory{
void draw(){
/*具体实现*/
}
}
具体工厂(三角形)
public class TriangleFactory implements ShapeFactory{
void draw(){
/*具体实现*/
}
}
画圆形
ShapeFactory factory= new CircleFactory();
Shape shape = factory.getShape();
shape.draw();
画正方形
ShapeFactory factory= new RectFactory();
Shape shape = factory.getShape();
shape.draw();
画三角形
ShapeFactory factory= new TriangleFactory();
Shape shape = factory.getShape();
shape.draw();
“工厂方法模式让一个类的实例化延迟到其子类”其实指的是,工厂方法模式先需要实例化工厂,然后才能用该工厂实例造对应的实例。而不是直接通过工厂类+静态方法来造实例。
抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部对产品族进行约束。所谓的产品族,一般或多或少的都存在一定的关联,抽象工厂模式就可以在类内部对产品族的关联关系进行定义和描述,而不必专门引入一个新的类来进行管理。
何时使用:
系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
缺点:
产品族的扩展将是一件十分费力的事情,假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。
实例:
图形接口:
public interface Shape{
void draw();
}
画圆形
public class Circle implements Shape{
@Override
void draw(){
/*具体实现*/
}
}
画正方形
public class Rectanglet implements Shape{
@Override
void draw(){
/*具体实现*/
}
}
画三角形
public class Triangle implements Shape{
@Override
void draw(){
/*具体实现*/
}
}
颜色接口
public interface Color {
void fill();
}
红色
public class Red implements Color {
@Override
public void fill() {
System.out.println("Inside Red::fill() method.");
}
}
绿色
public class Green implements Color {
@Override
public void fill() {
System.out.println("Inside Green::fill() method.");
}
}
蓝色
public class Blue implements Color {
@Override
public void fill() {
System.out.println("Inside Blue::fill() method.");
}
}
抽象工厂
public abstract class AbstractFactory {
public abstract Color getColor(String color);
public abstract Shape getShape(String shape) ;
}
图形工厂
public class ShapeFactory extends AbstractFactory {
@Override
public Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("circle")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("rectangle")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("triangle")){
return new Triangle();
}
return null;
}
@Override
public Color getColor(String color) {
return null;
}
}
颜色工厂
public class ColorFactory extends AbstractFactory {
@Override
public Shape getShape(String shapeType){
return null;
}
@Override
public Color getColor(String color) {
if(color == null){
return null;
}
if(color.equalsIgnoreCase("red")){
return new Red();
} else if(color.equalsIgnoreCase("green")){
return new Green();
} else if(color.equalsIgnoreCase("blue")){
return new Blue();
}
return null;
}
}
工厂创造器
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;
}
}
Test
public class Test {
public static void main(String[] args) {
//获取形状工厂
AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
//获取形状为 Circle 的对象
Shape shape1 = shapeFactory.getShape("circle");
//调用 Circle 的 draw 方法
shape1.draw();
//获取形状为 Rectangle 的对象
Shape shape2 = shapeFactory.getShape("rectangle");
//调用 Rectangle 的 draw 方法
shape2.draw();
//获取形状为 Triangle 的对象
Shape shape3 = shapeFactory.getShape("triangle");
//调用 Triangle 的 draw 方法
shape3.draw();
//获取颜色工厂
AbstractFactory colorFactory = FactoryProducer.getFactory("color");
//获取颜色为 Red 的对象
Color color1 = colorFactory.getColor("red");
//调用 Red 的 fill 方法
color1.fill();
//获取颜色为 Green 的对象
Color color2 = colorFactory.getColor("green")
//调用 Green 的 fill 方法
color2.fill();
//获取颜色为 Blue 的对象
Color color3 = colorFactory.getColor("blue");
//调用 Blue 的 fill 方法
color3.fill();
}
}
抽象工厂中,一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。