您的位置:首页 > 编程语言 > Java开发

Spring设计模式探幽(1)

2017-08-24 16:30 190 查看

设计伊始

Spring 是为解决企业级应用开发的复杂性而设计,她可以做很多事。但归根到底支撑Spring的仅仅是少许的基本理念,而所有地这些的基本理念都能可以追溯到一个最根本的使命:简化开发。这是一个郑重的承诺,其实许多框架都声称在某些方面做了简化。

而Spring则立志于全方面的简化Java开发。对此,她主要采取了4个关键策略:

1,基于POJO的轻量级和最小侵入性编程;

2,通过依赖注入和面向接口松耦合;

3,基于切面和惯性进行声明式编程;

4,通过切面和模板减少样板式代码;

而他主要是通过:面向Bean、依赖注入以及面向切面这三种方式来达成的。
而设计如此精妙的spring,其中肯定是有许多设计模式的,下面我们就通过阅读分析spring的源码来感受spring的密码。
贴一个spring源码下载地址,下载托管在github了。 https://github.com/spring-projects/spring-framework/tags 我下的是spring3.2.5 release


常见的九种设计模式

分别是:简单工厂、工厂方法、单例模式、适配器模式、包装器模式、代理模式、观察者模式、策略模式、模板方法模式

1.工厂模式

org.springframework.beans.factory 这里是定义spring IOC容器接口的包,在这个包里有我们熟悉的BeanFactory

package org.springframework.beans.factory;

public interface BeanFactory {

/**
*这里是对FactoryBean的转义定义,如果使用bean的名字检索FactoryBean,得到的是工厂生成的对象,
*如果需要得到工厂本身,需要转义。For example, if the bean named
* <code>myJndiObject</code> is a FactoryBean, getting <code>&myJndiObject</code>
* will return the factory
*/
String FACTORY_BEAN_PREFIX = "&";

/**
*这里根据bean的名字,在IOC容器中得到bean实例,这个IOC容器就是一个大的抽象工厂。
*/
Object getBean(String name) throws BeansException;

/**
*这里根据bean的名字和Class类型来得到bean实例,和上面的方法不同在于它会抛出异常:如果
*根据名字取得的bean实例的Class类型和需要的不同的话。
*/
Object getBean(String name, Class requiredType) throws BeansException;

/**
*这里提供对bean的检索,看看是否在IOC容器有这个名字的bean
*/
boolean containsBean(String name);

/**
*这里根据bean名字得到bean实例,并同时判断这个bean是不是单例
*/
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

/**
*这里得到bean实例的Class类型
*/
Class getType(String name) throws NoSuchBeanDefinitionException;

/**
*这里得到bean的别名,如果根据别名检索,那么其原名也会被检索出来
*/
String[] getAliases(String name);
}


spring中BeanFactory和ApplicationContext的创建中都用到了典型的静态工厂模式。Bean 的创建采用了的工厂模式,他的顶级接口是 BeanFactory。BeanFactory 有三个子接口:ListableBeanFactory、HierarchicalBeanFactory 和 AutowireCapableBeanFactor。这三个接口主要是为了区分在 Spring 内部在操作过程中对象的传递和转化过程中,对对象的数据访问所做的限制。这三个子接口集成了顶级接口并对BeanFactory的功能进行了增强,称为二级接口;ConfigurableBeanFactory对二级接口HierarchicalBeanFactory进行了再次增强,它还继承了另一个外来的接口SingletonBeanRegistry,可以被称为三级接口;ConfigurableListableBeanFactory是一个更强大的接口,继承了上述的所有接口,称为四级接口。其余的为抽象类,实现了Spring Bean四级接口所定义的所有功能。



一般来说采用BeanFactory的子接口ApplicationContext来创建BeanFactory的实例。ApplicationContext通常使用如下两个实现类:

FileSystemXmlApplicationContext:以基于文件系统的XML配置文件创建ApplicationContext实例。

ClassPathXmlApplicationContext:以类加载路径下的XML配置文件创建的ApplicationContext实例

public void testAC() {

//1.在这里ApplicationContext接口继承了ListableBeanFactory, HierarchicalBeanFactory等二级接口

ApplicationContext ac = new ClassPathXmlApplicationContext("cn/xyf/a_hello/applicationContext.xml");

//2.从容器获取Bean
User user = (User) ac.getBean("user");

System.out.println(user);

}


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

在这里给出简单工厂模式的实现

//简单工厂模式
package cn.xyf.factory;

/**
* @author Dale
*  封装一个雷峰类
*/
public class LeiFeng {
//扫地
public void sweep(){
System.out.println("扫地");
}

//洗衣
public void wash(){
System.out.println("洗衣");
}

//买米
public void buyRice(){
System.out.println("买米");
}
}

//大学生子类
class UnderGraduate extends LeiFeng{

}

//社区志愿者子类
class Volunteer extends LeiFeng{

}

package cn.xyf.factory;

/**
* @author Dale
* 简单工厂模式
*/
public class SimpleFactory {
//静态方法创建雷锋对象
public static LeiFeng createLeiFeng(String type){
LeiFeng result = null;
switch(type){
case "UnderGraduate":
result = new UnderGraduate();
break;
case "UnderGrate":
result = new Volunteer();
break;
}
return result;
}
}

package cn.xyf.factory;

/**
* @author Dale
* java 工厂模式
*/
public class Client {

public static void main(String[] args) {
//1.简单工厂模式
LeiFeng s1 = SimpleFactory.createLeiFeng("UnderGraduate");
LeiFeng s2 = SimpleFactory.createLeiFeng("UnderGrate");
s1.wash();
s2.buyRice();

}


在这里补充一下简单工厂、工厂、抽象工厂三者的区别

简单工厂

简单工厂模式的工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。

不修改代码的话,是无法扩展的。

工厂方法

工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。

在同一等级结构中,支持增加任意产品。

抽象工厂

抽象工厂是应对产品族概念的。比如说,每个汽车公司可能要同时生产轿车,货车,客车,那么每一个工厂都要有创建轿车,货车和客车的方法。

应对产品族概念而生,增加新的产品线很容易,但是无法增加新的产品。

小结

★工厂模式中,重要的是工厂类,而不是产品类。产品类可以是多种形式,多层继承或者是单个类都是可以的。但要明确的,工厂模式的接口只会返回一种类型的实例,这是在设计产品类的时候需要注意的,最好是有父类或者共同实现的接口。

★使用工厂模式,返回的实例一定是工厂创建的,而不是从其他对象中获取的。

★工厂模式返回的实例可以不是新创建的,返回由工厂创建好的实例也是可以的。

区别

简单工厂 : 用来生产同一等级结构中的任意产品。(对于增加新的产品,无能为力)

工厂方法 :用来生产同一等级结构中的固定产品。(支持增加任意产品)

抽象工厂 :用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)

以上三种工厂 方法在等级结构和产品族这两个方向上的支持程度不同。所以要根据情况考虑应该使用哪种方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring-设计模