首页 > 其他 > 详细

案例分析:设计模式与代码的结构特性

时间:2019-12-07 16:58:15      阅读:114      评论:0      收藏:0      [点我收藏+]

我的工程实践项目是Java Web相关,使用了Spring框架。

在Java面向过程的概念中:一切皆对象!但是大量对象的创建、调用和删除在大型项目中是一件很复杂的事情,而Spring框架大大简化了这一过程。众所周知,Spring框架的核心就是IOC,把对象的创建、管理和删除全部交给IOC容器管理。这就免不了工厂模式的使用。

 

那么什么是工厂模式?

举一个简单的例子。假如我们制作一款绘图工具。可以绘制圆形,正方形,三角形等各种图形,每个图形都有一个draw()方法用于绘图。如果我们需要创建一个图形,对于Java面向对象来说,我们并不需要亲自去绘制,只需要下达相关的指令,由能够解析指令的工具自动帮我们完成就好。在工厂模式中,工厂类就是这个能解析指令自动完成的重要工具,我们把所有的逻辑业务都交给工厂去办。

 

为什么要用工厂模式?

对于调用者来说,工厂模式隐藏了复杂的逻辑处理过程,调用者只关心执行结果,而由工厂类保证生产出符合规范的产品。有以下三个好处:

(1) 解耦 :把对象的创建和使用的过程分开。

(2) 降低代码重复: 如果创建某个对象的过程都很复杂,需要一定的代码量,而且很多地方都要用到,那么就会有很多的重复代码。

(3) 降低维护成本 :由于创建过程都由工厂统一管理,所以发生业务逻辑变化,不需要找到所有需要创建对象B的地方去逐个修正,只需要在工厂里修改即可,降低维护成本。

 

工厂模式的具体实现?

工厂模式分为三种:

1.简单工厂模式,只适合简单的情况。

2.工厂方法模式,把简单的工厂模式抽象化了,适合更加复杂的程序设计。

3.抽象工厂模式,工厂类中只写一个抽象方法,让其他类继承并重写该方法。

 

介绍一下简单工厂模式。我们必须制作一个工厂(Factory)角色 :它是简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。

 

假如我们制作一款绘图工具。可以绘制圆形,正方形,三角形等各种图形,每个图形都有一个draw()方法用于绘图。我们可以定义一个工厂类ShapeFactory,它会根据指令创建不同形状的形状类并返回,而不需要用户亲自去创建。

public class ShapeFactory {

    // 使用 getShape 方法获取形状类型的对象
    public static 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("SQUARE")) {
            return new Square();
        }
        return null;
    }
}

 

 

这样一来,如果我们想创建图形类,就可以直接通过工厂类ShapFactory的getShape方法得到新建的 circle/rectangle/square 对象并使用。

public class Test {

    public static void main(String[] args) {

        // 获取 Circle 的对象,并调用它的 draw 方法
        Shape circle = ShapeFactory.getShape("CIRCLE");
        circle.draw();

        // 获取 Rectangle 的对象,并调用它的 draw 方法
        Shape rectangle = ShapeFactory.getShape("RECTANGLE");
        rectangle.draw();

        // 获取 Square 的对象,并调用它的 draw 方法
        Shape square = ShapeFactory.getShape("SQUARE");
        square.draw();
    }
}

 

简单工厂模式代码简单,逻辑清晰,但通常简单带来的弊病就是后期维护难。假如我们有一个新的成员要加入,那么就需要修改工厂类,这就完全违背了ocp(对扩展开放,对修改封闭)原则。如果想改善这一点,一方面可以使用反射机制(Spring也用到了这个方法,但因为篇幅问题不再展开),另一方面,可以该用工厂方法模式,这也是在工厂模式家族中是用的最多模式。

工厂方法模式是简单工厂的仅一步深化, 在工厂方法模式中,我们不再提供一个统一的工厂类来创建所有的对象,而是针对不同的对象提供不同的工厂。也就是说 每个对象都有一个与之对应的工厂 。

//接口
public interface Factory {
    public Shape getShape();
}

//圆形工厂类
public class CircleFactory implements Factory {

    @Override
    public Shape getShape() {
        // TODO Auto-generated method stub
        return new Circle();
    }

}

//三角形工厂类
public class RectangleFactory implements Factory{

    @Override
    public Shape getShape() {
        // TODO Auto-generated method stub
        return new Rectangle();
    }

}

//长方形工厂类
public class SquareFactory implements Factory{

    @Override
    public Shape getShape() {
        // TODO Auto-generated method stub
        return new Square();
    }

}

这样当我们想创建一个圆形对象时,只需要调用相应的工厂类来实现。

public class Test {

    public static void main(String[] args) {
        Factory circlefactory = new CircleFactory();
        Shape circle = circlefactory.getShape();
        circle.draw();
    }

}

 

那么什么是抽象工厂模式

抽象工厂模式是工厂方法的仅一步深化,在这个模式中的工厂类不单单可以创建一种产品,而是可以创建一组产品。当我们需要一组对象共同完成某种功能时,并且可能存在多组对象完成不同功能的情况(同属于同一个产品族的产品)且系统结构稳定,不会频繁的增加对象时(因为一旦增加就需要修改原有代码,不符合开闭原则),我们可以采用抽象工厂方法。

 

比方说,我们绘制圆形时,往往还要返回一个点的集体类来确定圆心。我们可以在同一个工厂内用不同的方法来实现。

public class circleFactory implements Factory{

    //确定圆心
    @Override
    public Dot getCentor() {
        return new Dot();
    }

    //绘图
    @Override
    public Circle getShape() {
        return new circle();
    }

}

 

这样我们就可以在一个工厂类里创建不同的对象组合。、

public class Test {

    public static void main(String[] args) {  

     Factory factory = new CircleFactory();
     Dot dot = factory.getCentor();
     dot.find();
     Circle circle = factory.getShape();
     circle.draw(); 

    }

}

 

Spring中工厂类的使用

 

在Spring框架中,定义了两个工厂类 BeanFactory 和 ApplicationContext ,来为容器自动创建bean(对象实体)服务,即实现getBean方法。两者有以下两个区别:

  1. ApplicationContext 是 BeanFactory 的子接口,提供了比父接口更多的功能。

  2. 在生成 bean 实例的时候,生成的时机是不一样的。BeanFactory 在工厂实例化后,在调用 getBean 时创建实例。ApplicationContext 在加载配置文件的时候,将配置文件中所有单例模式生成的类全部实例化。

 

在框架使用过程中,我们就可以通过工厂类读取XML配置文件,实现对bean的实例化。

@Test
public void demo() {
    //创建工厂类
    BeanFactory beanFactory = new XmlBeanFactory(new FileSystemResource("e:\\applicationContext.xml"));
    //通过工厂获得类
    UserService userService = (UserService) beanFactory.getBean("userService");
    //通过对象执行方法
    userService.sayHello();
}

 

在Spring框架使用Bean管理对象,大大降低了项目的耦合性。各个对象之间不再有复杂的耦合关系,只和IOC容器类进行耦合,互相不再干扰。为项目开发的模块化、封装做出了重要贡献。

 

在以前刚刚学习Spring框架的时候,也自己尝试实现过一些简单的IOC容器,来实现工厂模式。因为年代久远,只找到了截图。把代码贴在下方,有助于理解其中的原理:

技术分享图片技术分享图片

案例分析:设计模式与代码的结构特性

原文:https://www.cnblogs.com/mrjoker97/p/12002011.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!