设计模式——Factory工厂模式

工厂模式

       实例化对象,用工厂方法代替new操作。定义一个创建对象的接口指向其实现的子类,让父类决定实例的生成方式,让子类决定实现的细节。这样有利于扩展。

工厂模式是Java中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。

应用实例: 1、JDBC中调用对数据库操作的API,而不必关系底层实现的是MySQL还是Oracle,只需要传入对应的类名。

优点: 1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口。

缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

 设计模式——Factory工厂模式

Shape.java

定义一个接口,规范对象使用行为。

public interface Shape {
   
void draw();
}

两个实现类

实现相同的接口,细节实现不同的功能。

public class Square implements Shape {
   
@Override
   
public void draw() {
        System.
out.println("我是方形");
   
}
}

 

public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("我是圆形");
    }
}

ShapeFactory.java

实现了三个方法分别对应不同的获取对象的方式,推荐使用第二和第三个方法,使用了反射机制,这样新增功能,比如三角形时,不用修改工厂类,而使用第一种方法需要修改。

public class ShapeFactory {

    //使用 getShape 方法获取形状类型的对象
    public static Shape getShape(String shapeType) {
        if (shapeType == null) {
            return null;
        }
        if ("Circle".equals(shapeType)) {
            return new Circle();
        } else if ("Square".equals(shapeType)) {
            return new Square();
        }
        return null;
    }

    //根据类名获取
    public static Shape getShapeByClassName(String className){
        Shape shape=null;
        try {
            shape = (Shape) Class.forName(className).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return shape;
    }

    //根据Class类型 获取
    public static <T> T getShape(Class<? extends T> clazz) {
        T obj = null;
        try {
            obj = (T) Class.forName(clazz.getName()).newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return obj;
    }
}

Test.java

测试,输出为:

我是圆形

我是方形

我是圆形

public class Test {
    public static void main(String[] args){
        Shape shape1 = ShapeFactory.getShape("Circle");
        shape1.draw();
        Shape shape2 = ShapeFactory.getShapeByClassName("factory.shapepack.Square");
        shape2.draw();
        Shape shape3 = ShapeFactory.getShape(Circle.class);
        shape3.draw();
    }
}

 

抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂

在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

能够提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。在一个工厂里聚合多个同类产品。这里理解上有一定困难,打个比方:

工作了,为了参加一些聚会,肯定有两套或多套衣服吧,比如说有商务装(成套,一系列具体产品)、时尚装(成套,一系列具体产品),即一系列具体产品。假设一种情况,某一个衣柜(具体工厂)只能存放某一种这样的衣服(成套,一系列具体产品),每次拿这种成套的衣服时也自然要从这个衣柜中取出了。用 OO 的思想去理解,所有的衣柜(具体工厂)都是衣柜类的(抽象工厂)某一个,而每一件成套的衣服又包括具体的上衣(某一具体产品),裤子(某一具体产品),这些具体的上衣其实也都是上衣(抽象产品),具体的裤子也都是裤子(另一个抽象产品)。

 设计模式——Factory工厂模式

示例代码,新增一个Color接口和Red和Blue两个实现类以及ColorFactory工厂类,类似于上面的Shape实现方式。

新增一个AbstractFactory抽象工厂类

public abstract class AbstractFactory {
    protected abstract Color getColor(String color);
    protected abstract Shape getShape(String shape) ;
}

ColorFactory和ShapeFactory继承该抽象工厂类,如ColorFactory:

public class ColorFactory extends AbstractFactory {
    //简单起见这里不使用反射机制
    public Color getColor (String colorType){
        if (colorType == null) {
            return null;
        }
        if ("Red".equals(colorType)) {
            return new Red();
        } else if ("Blue".equals(colorType)) {
            return new Blue();
        }
        return null;
    }

    @Override
    //getShape不具体实现,让ShapeFactory去实现
    protected Shape getShape(String shape) {
        return null;
    }
}

新增一个工厂生成器类来获取对应的具体的工厂

FactoryProducer

public class FactoryProducer {
    public static AbstractFactory getFactory(String choice){
        //这里简单起见不使用反射机制
        if("Shape".equals(choice)){
            return new ShapeFactory();
        } else if("Color".equals(choice)){
            return new ColorFactory();
        }
        return null;
    }
}

 

测试输出:

我是方形

填充红色

AbstractFactory shapeFactory = FactoryProducer.getFactory("Shape");
shapeFactory.getShape("Square").draw();
AbstractFactory colorFactory = FactoryProducer.getFactory("Color");
colorFactory.getColor("Red").fill();

 

相关文章: