博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring中的设计模式
阅读量:6624 次
发布时间:2019-06-25

本文共 4986 字,大约阅读时间需要 16 分钟。

hot3.png

 

         设计模式作为一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,在现代软件开发过程中得到了充分的利用。使代码更容易被他人理解,保证代码的可靠性。对于一个尚未接触过大型软件开发的学生,在软件开发过程中我使用的设计模式也比较少,并且通常是利用现有框架进行软件的开发,因此,我学习了一下在spring框架中所使用到的设计模式,并就此做一些总结和尝试。在java众多开源框架中,作为一个轻量级java开发框架,spring经过十几年的发展,已经成为了java SE/EE最流行的开发框架,无论在架构设计方面还是代码编写方面,都看成行内典范。

    Spring中常用的设计模式有九种,下面将选择其中的两种做详细的介绍。

    第一种,简单工厂模式。简单工厂模式又叫静态工厂方法模式,但是不属于23种经典模式之一。简单来说,简单工厂模式就是定义一个类来专门创建其他类的实例,被创建的实例通常具有相同的父类。

    举一个简单的例子就是小明想请一些同学吃饭,但是他自己又不会做饭,所以小明将同学带到了肯德基,同学们自己点餐,而他只负责付钱。那么在这里,肯德基就是一个食物工厂,同学小红点了一份炸鸡,工厂就实例化一份炸鸡;小华点了一份汉堡,工厂就实例化一份汉堡。所有食物都继承自“食物”接口。

    如图创建5个类:

   

Food接口:

    public interface Food {

 

    public void get();

}

Chicken类:

    public class Chicken implements Food {

   

    public void get() {

        System.out.println("chicken");

    }

}

Hamburg类:

    public class Hamburg implements Food {

   

    public void get() {

        System.out.print("hamburg");

    }

}

工厂类:

    public class FoodFactory {

 

    public static Food getFood(String food) throws Exception{

        if(food.equalsIgnoreCase("chicken")){

            return Chicken.class.newInstance();

        }else if(food.equalsIgnoreCase("hamburg")){

            return Hamburg.class.newInstance();

        }else{

            System.out.print("There is no such food!");

            return null;

        }

    }

}

最后是测试:

    public class Test {

 

    public static void main(String []args) throws Exception {

        String xiaohong = "chicken";

        String xiaohua = "hamburg";

 

        Food a = FoodFactory.getFood(xiaohong);

        Food b = FoodFactory.getFood(xiaohua);

        a.get();

        b.get();

    }

}

 

输出结果如图所示:

   

返回了小红和小华点的对应食物。

 

    在spring中,BeanFactory拥有类似的功能,它负责实例化、配置和管理对象。我们一般用的BeanFactory的实现类ApplicationContext,这个类会自动解析我们配置的applicationContext.xml,然后根据我们配置的bean来new对象,将new好的对象放进一个Map中,键就是我们bean的id,值就是new的对象。下面是一个简化版的BeanFactory的应用:

 

BeanFactory接口:

public interface BeanFactory {

    Object getBean(String id);

}

 

一个BeanFactory的实现类ClassPathXmlApplicationContext,用以读取配置信息:

public class ClassPathXmlApplicationContext implements BeanFactory {

    private Map<String, Object> beans = new HashMap<String, Object>();

    public ClassPathXmlApplicationContext(String fileName) throws Exception{

        SAXReader reader = new SAXReader();

        Document document = reader.read(this.getClass().getClassLoader().getResourceAsStream(fileName));

        List<Element> elements = document.selectNodes("/beans/bean");

        for (Element e : elements) {

            String id = e.attributeValue("id");

            String value = e.attributeValue("class");

            Object o = Class.forName(value).newInstance();

            beans.put(id, o);

        }

    }

    public Object getBean(String id) {

        return beans.get(id);

    }

}

 

配置信息applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans>

    <bean id="c" class="com.spring.Car"></bean>

    <bean id="p" class="com.spring.Plane"></bean>

</beans>

 

测试类:

public class Test {

    public static void main(String[] args) throws Exception {

        BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");

        Object o = factory.getBean("c");

        System.out.println(o.getClass().toString());

    }

 

}

 

输出结果:

 

    以上就是spring中工厂模式的应用的一个例子。BeanFactory只是其中的一种应用,spring中还有很多工厂模式的应用,留待以后认真学习。

 

 

    第二种,装饰模式。装饰模式也叫包装器模式,指动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。

一个简单的例子就是用户需求打印一句话,那么就可以这样实现:

 

接口PrintHandler:

public interface PrintHandler { 

    public String filter(String msg); 

 

接口实现类PrintMessage:

public class PrintMessage implements PrintHandler { 

    public String filter(String msg) { 

        return msg; 

    } 

 

测试类Test:

public class Test { 

     public static void main(String[] args) { 

          PrintHandler ph = new PrintMessage (); 

          String s = ph.filter("今天天气真好!"); 

          System.out.println(s); 

       } 

 

输出结果为:

 

    现在客户提出了新的需求,需要在输出信息前面加上“提示信息”几个字。直接更改PrintMessage实现类不太好,因为可能在软件其他地方使用到了该方法。那么就可以用到装饰器模式,代码如下:

 

装饰器类PrintHandlerDecorator

public class PrintHandlerDecorator implements PrintHandler { 

     private PrintHandler handler; 

     public PrintHandlerDecorator(PrintHandler handler) { 

         super(); 

         this.handler = handler; 

       } 

     public String filter(String msg) { 

         return handler.filter(msg); 

       } 

 

具体实现类DetailDecorator:

public class DetailDecorator extends PrintHandlerDecorator { 

    public DetailDecorator (PrintHandler handler) { 

        super(handler); 

    } 

    public String filter(String content) { 

        String temp = "提示信息"; 

        temp += super.filter(content); 

        return temp; 

       } 

 

测试类Test:

public class Test { 

       public static void main(String[] args) { 

          PrintHandler mb = new PrintMessage (); 

          mb = new PrintHandlerDecorator (new DetailDecorator (new PrintMessage ())); 

          content = mb.filter("今天天气真好"); 

          System.out.println(content); 

          } 

 

以上就是装饰模式的一个简单的例子,在spring中,开发人员最熟悉的装饰模式的应用应该就是dataSource了。有时在项目中需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。我们以往在spring和hibernate框架中总是配置一个数据源,因而sessionFactory的dataSource属性总是指向这个数据源并且恒定不变,所有DAO在使用sessionFactory的时候都是通过这个数据源访问数据库。但是现在,由于项目的需要,我们的DAO在访问sessionFactory的时候都不得不在多个数据源中不断切换,这就给开发带来了相当大的难度和性能影响。

在spring的applicationContext中可以配置所有的dataSource。这些dataSource可能是各种不同类型的,比如不同的数据库:Oracle、SQL Server、MySQL等,也可能是不同的数据源:比如apache 提供的org.apache.commons.dbcp.BasicDataSource、spring提供的org.springframework.jndi.JndiObjectFactoryBean等。然后sessionFactory根据客户的每次请求,将dataSource属性设置成不同的数据源,以到达切换数据源的目的。

spring中用到的包装器模式在类名上有两种表现:一种是类名中含有Wrapper,另一种是类名中含有Decorator。基本上都是动态地给一个对象添加一些额外的职责。

总之,作为一款优秀的框架,spring在设计模式上的应用显得非常巧妙,还需要我更深入的理解学习。

转载于:https://my.oschina.net/u/2248183/blog/783449

你可能感兴趣的文章
java thread中的wait()和notify()
查看>>
2016最新搜索引擎优化(SEO)重点要素
查看>>
当Web访问性能出现问题,如何深探?
查看>>
【IOS-COCOS2D-X 游戏开发之二】【必看篇】总结阐述COCOS2D-X与COCOS2D-IPHONE区别;
查看>>
ExtJs之Ext.core.Element
查看>>
六套 App:构建我的产品设计工作流
查看>>
eoLinker-API_Shop_通讯服务类API调用的代码示例合集:短信服务、手机号归属地查询、电信基站查询等...
查看>>
因为小程序的scroll-view组件不能下拉刷新我做了个开源项目
查看>>
JavaScript 垃圾回收机制
查看>>
前端面试回忆录 - 滴滴篇 - 凉面
查看>>
jxl导入Excel 切割List 并使用MyBatis批量插入数据库
查看>>
BMIP002协议介绍
查看>>
前端的一些基础知识
查看>>
小程序开发总结
查看>>
win10系统设置webp文件默认用照片查看器打开的两种方法
查看>>
使用阿里云发送邮件
查看>>
Tomcat监听器设计思路
查看>>
react native 入门之javascript
查看>>
管理ORACLE实例
查看>>
Confluence 6 MySQL 数据库设置准备
查看>>