设计模式(一)工厂模式

工厂模式(Factory Pattern)是 Java 中最经常使用的设计模式之一。这种类型的设计模式属于建立型模式,它提供了一种建立对象的最佳方式。咱们熟悉的Spring 的 bean 工厂等。java

直接上demo.先代码,后介绍。spring

1. 编写接口Shape

Shape .java设计模式

/** * 一个接口:关于形状 */
public interface Shape {
    /** * 描述方法 */
    void describe();
}复制代码

2. 编写实现类

Circle .javabash

public class Circle implements Shape {
    /** * 描述方法 */
    @Override
    public void describe() {
        System.out.println("我是个圆形");
    }
}
复制代码

Rectangle .java框架

public class Rectangle implements Shape {
    /** * 描述方法 */
    @Override
    public void describe() {
        System.out.println("我是一个长方形");
    }
}
复制代码

3. 编写工厂类ShapeFactory

ShapeFactory .javaide

/** * 形状工厂 */
public class ShapeFactory {
    public Shape getShape(String type){
        if (type == null){
            return null;
        }
        if ("CIRCLE".equals(type)){
            return new Circle();
        }else if ("RECTANGLE".equals(type)){
            return new Rectangle();
        }
        return null;
    }
}
复制代码

4. 测试

public class Test {
    public static void main(String[] args) {

        ShapeFactory shapeFactory = new ShapeFactory();
        //获取 圆形 实例化对象
        Shape circle = shapeFactory.getShape("CIRCLE");
        //调用对象方法
        circle.describe();

        //获取 长方形 实例化对象
        Shape rectangle = shapeFactory.getShape("RECTANGLE");
        //调用方法
        rectangle.describe();

    }
}
复制代码
我是个圆形
我是一个长方形
复制代码

5. 进阶

提问:若是你是一个爱动脑筋的人,你会发现,它和Bean工厂的做用是类似的,可是Bean工厂是这样实现的吗?它会自动去写if语句去建立实例对象吗?学习

答案确定是否是的。测试

固然,在这里不会像spring 的bean工厂同样,把它的逻辑写出来,由于人家已是通过不少年的迭代的产品,封装的已经(目不忍视)太厚了,因此把它的实现原理说明。优化

可能有些人都想到了,对,就是框架离不开的:反射机制。spa

5.1 优化工厂类代码

ShapeFactory.java

/** * 反射 */
    public Object getShape(Class<? extends Shape> clazz){
        Object object = null;

        try {
            object = Class.forName(clazz.getName()).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return object;
    }
复制代码

5.2 测试

Object shape = (Rectangle)shapeFactory.getShape(Rectangle.class);
        ((Rectangle) shape).describe();
复制代码

6 新的问题

若是忘记去对shapeFactory 作强制类型转换的话,那就是一个彻底的object对象,使用不方便,那如何可以省略类型转换的这一步骤呢?

6.1 再优化工厂类

/** * 反射 + 泛型 */
    public <T> T getShape(Class<? extends T> clazz){
        T object = null;
        try {
            //实例化,并在这里作 类型转换
            object = (T) Class.forName(clazz.getName()).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return object;
    }
复制代码

6.2 测试类

Rectangle shape = shapeFactory.getShape(Rectangle.class);
        shape.describe();
复制代码
我是一个长方形
复制代码

能够看到,事实上也是作了强制类型转换的,只不过在ShapeFactory里作的,看不到而已,这种作法会大大方便咱们使用。

7. 最后的甜点

通过第五点和第六点的学习,想一想,spring 框架里 其实只有一个工厂,那就是BeanFactory,ApplicationContext 也须要用它来建立对象。那如何去写一个针对多个接口实现一个公共的工厂类呢?

/** * 针对多个接口实现一个公共的工厂类 */
    public <T> Object getObject(Class<T> clazz) {
        if (clazz == null ) {
            return null;
        }
        Object obj  = null;
        try {
            obj = Class.forName(clazz.getName()).newInstance();
        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return obj;
    }
复制代码

8. 总结

一个思考题,咱们在Spring 框架下,@Autowired 装配Bean 具体是完成什么样的操做呢,这可能也是工厂模式最好的总结说明。

相关文章
相关标签/搜索