首页 > 代码库 > spring中用到的设计模式

spring中用到的设计模式

http://www.cnblogs.com/pengmengnan/p/6717766.html

 

 

一 : 工厂模式
工厂模式主要是为创建对象提供过度接口,以便将创建对象的具体 
过程屏蔽隔离起来,达到提高灵活性的目的.
工厂模式可以分为三类 : 
(1)简单工厂模式(simple factory)
(2)工厂方法模式 (factory method)
(3)抽象工厂模式(abstract factory)
( 一 ): 简单工厂模式
又称为静态工厂方法模式用来生产统一登记结构中任意产品,通过 
建立一个工厂(一个函数或一个类方法)来制造新的对象.
模式组成结构 : 
抽象产品:他一般视具体产品继承的父类或实现的接口.在java代 
码中由接口或者抽象类来实现.
具体产品: 工厂类所创建的对象就是此角色的实例.在java中有一 
个具体类来实现.
工厂类 : 这是本模式的核心,含有一定的商业逻辑和判断逻辑.在 
java中它往往由一个具体类实现.
示例代码:
抽象产品:
public interface Car{
void run();
}
具体产品 : 
public class Audi implements Car {
public void run(){
System.out.println("奥迪车");
}
}
public class BenChi implements Car{
public void run(){
System.out.println("奔驰");
}
}
工厂类 :
public class SimpleFactory{
public Car createrCar(String type){
if("奥迪".equals(type)){
return new Audi();
}else if("奔驰".equals(type)){
return new BenChi ();
}else {
return null;
}
}
}
客户类(测试类) :
public class Customer {
public static void main(String [] args ) {
SimpleFactory factory = new SimpleFactory ();
Car car1 = factory .createrCar("奥迪");
Ca r car2 = factory .createrCar("奔驰");
}
}

这边是简单的工厂模式,但是工厂部分不太理想,因为每增加一种新 
车型,都要在工厂中增加相应的创建业务逻辑,这显然是违背开闭原 
则的.可想而知对于新的产品的加入,工厂类很是被动.
于是工厂方法模式出现了,工厂类定义成了接口,而每新增的车型种 
类,就增加该车种类对应的工厂类的实现,这样工厂的设计就可以拓 
展了,而不必去修改源代码.
(二) : 工厂方法模式
工厂方法模式是简单工厂模式的进一步抽象化和推广,工厂方法模 
式里不在只由一个工厂类决定哪一个产品被实例化,这个决定交给 
抽象工厂的子类去做.
模式组成结构 : 
抽象产品: 他一般视具体产品集成的父类或者实现的接口.在java 
中有接口或者抽象类来实现.
具体产品 : 工厂类所创建的对象就是此角色的实例..在java中有 
一个具体类实现.
抽象工厂 : 这是工厂方法模式的核心,它与应用程序无关.是具体 
工厂角色实现的接口或者必须继承的父类.在java由接口或者抽象 
类来实现.
具体工厂 : 它含有和具体业务逻辑有关的代码.有应用程序调用 
以创建对应的具体产品的对象.
示例代码 : 
抽象产品:
public interface Car{
void run();
}
具体产品 : 
public class Audi implements Car {
public void run(){
System.out.println("奥迪车");
}
}
public class BenChi implements Car{
public void run(){
System.out.println("奔驰");
}
}

抽象工厂 : 
public interface CarFactory{
Car createCar();
}

具体工厂:
public class AuiFactory implements CarFactory{
publuic Car createCar(){
return new Audi();
}
}
public class BenChiFactory implements CarFactory{
publuic Car createCar(){
return new BenChi();
}
}
客户类:
public class Customer {
public static void main(String [] args ) {
Car car1 = new AuiFactory .createCar();
Car car2 = new .BenChiFactory .createCar();
}
}
简单工厂模式VS工厂方法模式
(1)结构复杂度:简单工厂模式更简单
(2)代码复杂度 : 简单工厂模式更少
(3)管理难度: 工厂方法模式的核心是一个抽象工厂类,而不是简单 
工厂模式,把核心放在一个类上拓展性更好,易于管理
根据设计理念建议使用工厂方法模式,但是实际上,我们一般使用简 
单工厂模式.
(三)抽象工厂模式:
抽象工厂模式提供一个创建一系列相关或相依赖对象的接口,而无 
需指定他们的具体的类.他针对的是有多个产品的等级结构.

反射机制

根据上面的工厂模式可以看出,根据需求要写出不同的对象实例化 
的方法,因此,spring引用了反射的思想:
根据类名可以找到其对应的类然后实例化对象,返回一个Object的 
类.
示例代码 : 
工厂类 :
public static Object getBean(String n){
if(n!=null&&!"".equals(n)){
try {
return 
Class.forName(n).newInstance(); // 通过类名 反射 实例化 
对象
} catch 
(InstantiationException e) {

e.printStackTrace();
} catch 
(IllegalAccessException e) {

e.printStackTrace();
} catch 
(ClassNotFoundException e) {

e.printStackTrace();
}
}
return null;

}

客户类:
IdCard u = (IdCard)Factory.getBean 
("com.jk.pojo.IdCard");
因为返回的是一个Object所以要强转
二 : 单例模式
一 : 饿汉模式 
特点:
在类装载的时候就初始化Singleton,有时候不是调用getInstance 
方法,调用别的静态方法,也会让类进行静态加载,但是,此时并不一 
定想实例化Singleton,造成资源的浪费.
这种方式基于classloder机制避免了多线程的同步问题,不过, 
instance在类装载时就实例化,虽然导致类装载的原因有很多种, 
在单例模式中大多数都是调用getInstance方法, 但是也不能确 
定有其他的方式(或者其他的静态方法)导致类装载,这时候初始 
化instance显然没有达到lazy loading的效果。
代码示例:
1. public class Singleton { 
2. private static Singleton instance = new 
Singleton(); 
3. private Singleton (){} //私有化有参构造
4. public static Singleton getInstance() { 
5. return instance; 
6. } 
7. }


二:饿汉模式变种
表面上看起来差别挺大,其实更第三种方式差不多,都是在类初始 
化即实例化instance。只是将实例化的对象放到了静态代码块中
示例代码:
1. public class Singleton { 
2. private Singleto+n instance = null; 
3. static { 
4. instance = new Singleton(); 
5. } 
6. private Singleton (){} 
7. public static Singleton getInstance() { 
8. return this.instance;
9. } 
10. } 
三 : 懒汉模式(线程安全的)
(1)
特点 : 没有加ysnchronized的懒汉模式,是线程不安全的,比如说 
一个线程来了判断instance是null,就去实例化Singleton了,在实 
例化之前,这是另一个线程来判断这个instance,发现也是null所 
以又去实例化一次,所以严格上来说不加synchronized懒汉模式, 
不是单例模式.synchronized 是让访问的客户自动去排队因此即 
使前面已经判断过不为空了,但后面的访问还是要一个一个的去排 
队访问,所以效率低
示例代码:
1. public class Singleton { 
2. private static Singleton instance; 
3. private Singleton (){} 
4. public static synchronized Singleton 
getInstance() { 
5. if (instance == null) { 
6. instance = new Singleton(); 
7. } 
8. return instance; 
9. } 
10. } 
(2)双重校验锁(重点)
加了双重校验锁的懒汉模式既可以使线程安全又不会影响效率,因 
为,第一次排队实例化第一个对象之后,下面在有访问的就直接被第 
一个if拦截住了,所以不需要去排队访问
示例代码
public class Singleton {
private Singleton(){};//私有化构造器
private static volatile Singleton instance = null; 
// volatile 不稳定
public static Singleton getInstance(){ // 
synchronized 同步锁 线程锁
if(instance==null){ // 双重判定锁 
synchronized (Singleton.class){
if(instance ==null){
instance = new Singleton ();
}
}
}
return instance ;
}
}
四 : 懒汉式(线程不安全)
这种写法lazy loading很明显,但是致命的是在多线程不能正常 
工作。比如说一个线程来了判断instance是null,就去实例化 
Singleton了,在实例化之前,这是另一个线程来判断这个 
instance,发现也是null所以又去实例化一次,所以严格上来说不 
加synchronized懒汉模式,不是单例模式.
1. public class Singleton { 
2. private static Singleton instance; 
3. private Singleton (){} 
4. 
5. public static Singleton getInstance() { 
6. if (instance == null) { 
7. instance = new Singleton(); 
8. } 
9. return instance; 
10. } 
11. }
五 : (静态内部类)
1. public class Singleton { 
2. private static class SingletonHolder { 
3. private static final Singleton INSTANCE = new 
Singleton(); 
4. } 
5. private Singleton (){} 
6. public static final Singleton getInstance() { 

7. return SingletonHolder.INSTANCE; 
8. } 
9. } 
这种方式同样利用了classloder的机制来保证初始化 
instance时只有一个线程,它跟第三种和第四种方式不同的是(很 
细微的差别):第三种和第四种方式是只要Singleton类被装载了 
,那么instance就会被实例化(没有达到lazy loading效果), 
而这种方式是Singleton类被装载了,instance不一定被初始化。 
因为SingletonHolder类没有被主动使用,只有显示通过调用 
getInstance方法时,才会显示装载SingletonHolder类,从而实 
例化instance。想象一下,如果实例化instance很消耗资源,我 
想让他延迟加载,另外一方面,我不希望在Singleton类加载时就 
实例化,因为我不能确保Singleton类还可能在其他的地方被主动 
使用从而被加载,那么这个时候实例化instance显然是不合适的。 
这个时候,这种方式相比第三和第四种方式就显得很合理
六 : 枚举
1. public enum Singleton { 
2. INSTANCE; 
3. public void whateverMethod() { 
4. } 
5. } 
这种方式是Effective Java作者Josh Bloch 提倡的方式,它不仅 
能避免多线程同步问题,而且还能防止反序列化重新创建新的对象 
,可谓是很坚强的壁垒啊,不过,个人认为由于1.5中才加入enum 
特性,用这种方式写不免让人感觉生疏,在实际工作中,我也很少 
看见有人这么写过

spring中用到的设计模式