已学过的设计模式(不断增加ing~)
2013-08-15 11:19
176 查看
一、单例设计模式(SINGLETON)
单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例单例模式。单例模式只应在有真正的“单一实例”的需求时才可使用。想要保证内存中只有一个实例,那么:
1、为了避免其他程序多过建立该对象,先禁止其他程序建立该对象
2、还为了让其他程序可以访问到该类对象,只好在本来中,自定义一个对象。
3、为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式
这三部用代码体现的方法为:
1、将构造函数私有化
2、在类中创建一个本类对象
3、提供一个方法可以获取到该对象
饿汉式:(推荐使用)
class Single
{
private Single(){};
private Single s = new Single();
public static Single getInstance()
{
return s;
}
}
懒汉式:
懒汉式既延迟加载,这种方式会出现线程安全隐患,所以需要加同步来解决问题,但是synchronized的执行效率非常低,所以不推荐使用同步函数,可以在同步代码块前后加入双层判断,以提高执行效率。
class Single
{
private Single(){};
private Single s = null;
public static Single getInstance()
{
if (s==null)
{
synchronized(Single.class)
{
if (s==null) //双重判断提高执行效率
{
s = new Single();
}
}
return s;
}
}
}
饿汉式单例类在自己被加载时就将自己实例化。即便加载器是静态的,在饿汉式单例
类被加载时仍会将自己实例化。单从资源利用效率角度来讲,这个比懒汉式单例类稍差些。
从速度和反应时间角度来讲,则比懒汉式单例类稍好些。然而,懒汉式单例类在实例化时,
必须处理好在多个线程同时首次引用此类时的访问限制问题,特别是当单例类作为资源控
制器,在实例化时必然涉及资源初始化,而资源初始化很有可能耗费时间。这意味着出现
多线程同时首次引用此类的机率变得较大。
饿汉式单例类可以在 Java 语言内实现,但不易在 C++内实现,因为静态初始化在 C++
里没有固定的顺序,因而静态的 m_instance 变量的初始化与类的加载顺序没有保证,可能
会出问题。饿汉式单例类更符合 Java 语言本身的特点。
双重检查成例对Java语言编译器不成立
在 C 语言里得到普遍应用的双重检查成例在多数的 Java语言编译器里
面并不成立[BLOCH01, GOETZ01, DCL01]。使用了双重检查成例的“懒汉式”单例类,
不能工作的基本原因在于,在 Java编译器中,LazySingleton类的初始化与单例变量
赋值的顺序不可预料。如果一个线程在没有同步化的条件下读取 单例变量 引用,并调用
这个对象的方法的话,可能会发现对象的初始化过程尚未完成,从而造成崩溃。
文献[BLOCH01]指出:一般而言,双重检查成立对 Java 语言来说是不成立的。
二、模板方法模式(TEMPLATE METHOD)
在定义功能时,功能的一部分是确定的,而另一部分是不确定的,但确定的那一部分功能在使用不确定的功能,这时候就需要将不确定的部分暴露出去,由该类的子类去完成。TemplateMethod使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
public abstract class TemplateMethod { public long runningTime() { long beginTime = System.currentTimeMillis(); run(); long endTime = System.currentTimeMillis(); return endTime-beginTime; } public abstract void run();//不确定的部分暴露出去,留给子类去实现 }
三、装饰设计模式(DECORATOR)
装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案,提供比继承更多的灵活性。动态给一个对象增加功能,这些功能可以再动态的撤消。增加由一些基本功能的排列组合而产生的非常大量的功能。装饰设计模式比一味的通过继承来实现扩展功能好在,他可以避免体系的臃肿,使得类与类之间更加灵活。
使用方法:
可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。那么自定义的该类称为装饰类。装饰类通常会通过构造方法接收被装饰的对象。并基于被装饰的对象的功能,提供更强的功能。
class Person
{
publicvoid chifan()
{
System.out.println("吃饭");
}
}
class SuperPerson
{
privatePerson p ;
SuperPerson(Personp)
{
this.p= p;
}
publicvoid superChifan()
{
System.out.println("开胃酒");
p.chifan();
System.out.println("甜点");
System.out.println("来一根");
}
}
class PersonDemo
{
publicstatic void main(String[] args)
{
Personp = new Person();
//p.chifan();
SuperPersonsp = newSuperPerson(p);
sp.superChifan();
}
}
四、享元模式(FLYWEIGHT)
运用共享技术有效地支持大量细粒度的对象。享元模式以共享的方式高效的支持大量的细粒度对象。享元模式能做到共享的关键是区分内蕴状态和外蕴状态。内蕴状态存储在享元内部,不会随环境的改变而有所不同。外蕴状态是随环境的改变而改变的。外蕴状态不能影响内蕴状态,它们是相互独立的。将可以共享的状态和不可以共享的状态从常规类中区分开来,将不可以共享的状态从类里剔除出去。客户端不可以直接创建被共享的对象,而应当使用一个工厂对象负责创建被共享的对象。享元模式大幅度的降低内存中对象的数量。
举例说明:
JDK1.5新特性中,基本类型自动拆装箱,其中将int类型数据装箱成Integer时,一个byte以内的数据均为同一个对象,即-128~127的数自动装箱后的对象内存地址相等。
Integer i1 = 13;
Integer i2 = 13;
System.out.println(i1==i2);//true
超出一个byte后,则内存地址不同
Integer i3 = 131;
Integer i4 = 131;
System.out.println(i3==i4);//false
不用自动装箱,而用静态方法也是一样
Integer i5 = Integer.valueOf(3);
Integer i6 = Integer.valueOf(3);
System.out.println(i5==i6); //true
Integer i55 = Integer.valueOf(333);
Integer i66 = Integer.valueOf(333);
System.out.println(i55==i66);//false
五、策略模式(STRATEGY)
策略模式针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。策略模把行为和环境分开。环境类负责维持和查询行为类,各种算法在具体的策略类中提供。由于算法和环境独立开来,算法的增减,修改都不会影响到环境和客户端。相关文章推荐
- 面向对象的设计模式的学习笔记,不断学习归纳总结ing
- 自定义分页控件(四)完善设计时支持和增加分页模式
- 设计模式的精要理解(不断更新)
- 从头认识设计模式-策略模式-02-解决方向一:在继承里面增加导入导出方法
- 增加一个间接层来解耦的所有设计模式总结
- iOS单例设计模式具体解说(单例设计模式不断完好的过程)
- Java-马士兵设计模式学习笔记-观察者模式-读取properties文件,动态增加观察者
- [置顶] iOS单例设计模式详细讲解(单例设计模式不断完善的过程)
- 随笔--研磨设计模式[不断更新]
- 从头认识设计模式-策略模式-03-解决方向二:在每一个类里面单独增加方法或者增加接口
- [设计模式]-外观模式(Facade)ing
- 设计模式好文章汇总(不断更新中)
- 设计模式学习笔记,不断更新中……
- 设计模式三(采用pyside为设计模式一、二增加GUI外衣 )
- [设计模式]-抽象工厂模式ing
- 关于JAVA设计模式(不断添加中...)
- vc 部分外挂相关代码,不断增加ing
- 学习设计模式ING
- [原版].NET 菜鸟如何 学习 设计模式 [不断修改中]
- [设计模式]-架构中的设计原则(笔记ing)