Hello
设计学习应用,好记性不如烂笔头,强调不是学习和小试牛刀,通过几遍文章资料,通过几段固定的代码就可以把设计模式的思想掌握的很好(当然不排除在座的各位中有骨骼精奇万中无一的奇才,明显本座不是),主要将设计的思维领悟,能应用到自己的项目,或者是工作环境中,不然永远是虚把式,提升自我的思考层次.
设计模式,许多在代码层级,逻辑上都是有套路的,更多我们需要了解知道模式使用的场景、意义, 思维思考方式的转换.
以上废话都是鼓励自己用的,请大家跳过即可.
下面是将要逐步学习应用的 GOF23"四人帮" 的设计模式.
模式分类
创建型模式 : ↓↓↓
--单例模式,工厂模式,抽象工厂模式,建造者模式,原型模式.
结构型模式 : ↓↓↓
--适配器模式,桥接模式,装饰模式,组合模式,外观模式,享元模式,代理模式.
行为型模式 : ↓↓↓
--模版方法模式,命令模式,迭代器模式,观察者模式,中介者模式,备忘录模式,解释器模式,状态模式,
策略模式,职责模式,访问者模式.
---------------------------以下开始本编内容---------------------------
单例模式
核心作用: 保证一个类中只有一个实例,并提供一个全局访问点.
只有一个实例,减少系统的开销,比如配置文件,其他API的依赖等,运行时只需要在内存中生成一份对象,而不需要每次去获取的时候new一个对象,多一份对象产生. 可以在全局设置访问点,优化资源访问.
朋友送我一只小狗,隔壁小妹妹想摸摸,我就拿给她摸摸,她很开心.楼上小姐姐想玩玩,我就抱给她玩玩,她也很开心.楼下大爷自己去抓狗溜,没有找我,当然是抓不到的了.
五种常见的方式
饿汉式
项目开始,不管后面会不会使用该类,类加载器都会加载该类
线程安全,调用率高,不能懒加载
1.需要有一个private的构造器,其他类无法调用其构造器初始化
2.还需要一个private static类变量并初始化
3.另外提供一个对外的public访问点,其他类只能在此处获取该对象
public class SingleZone { //类加载器加载,是线程安全的 private static SingleZone single=new SingleZone(); private SingleZone() { } public static SingleZone getSingle(){ return single; } }
懒汉式
线程安全,调用率不高,可以懒加载
1.需要有一个private的构造器,其他类无法调用其构造器初始化
2.还需要一个private static类变量不初始化
3.另外提供一个对外的public访问点,其他类只能在此处获取该对象
4.多线程情况下,在全局访问点(getSingle()方法)加上synchronized修饰,自然的并发效率会低一点
public class SingleOne { //定义不初始化 private static SingleOne single; private SingleOne() { } //需要的时候才会初始化对象 public synchronized static SingleOne getSingle(){ if (single==null){ single=new SingleOne(); } return single; } }
双重检测锁式(了解即可,参考)
public class SingleTwo {
private static SingleTwo singleTwo=null;
private SingleTwo(){
}
public SingleTwo getSingleTwo(){
if (singleTwo==null){
SingleTwo singleTwo1;
synchronized (SingleTwo.class){
singleTwo1=singleTwo;
if (singleTwo1==null){
synchronized (SingleTwo.class){
if(singleTwo1==null){
singleTwo1=new SingleTwo();
}
}
}
singleTwo=singleTwo1;
}
}
return singleTwo;
}
}
静态内部类式
线程安全,调用率高,可以延迟加载
1.外部类没有static定义和初始化,不会立即加载对象
2.只有需要时调用访问点,才能获取到对象,加载类是线程安全的
3.内部类有static (final)修饰,在内存内确保只有一份对象,只能被赋值一次,线程安全
4.具备并发,懒加载的优点
public class SingleThree {
private SingleThree(){
}
//通过静态内部类初始化 SingleThree外部类
private static class SingleInnerClass{
private static final SingleThree singleThree=new SingleThree();
}
//需要的时候调用即可
public SingleThree getSingleThree(){
return SingleInnerClass.singleThree;
}
}
枚举单例式
枚举元素本身是单例模式,没有懒加载,在JVM下,避免反射,反序列化的影响.
每一个枚举实例都是static final类型,表示只能被实例化一次,Java规范中规定,每一个枚举类型极其定义的枚举变量在JVM中都是唯一的,反序列化后的实例也会和之前被序列化的对象实例相同,保证枚举序列化单例.
public enum SingleFour { INSTANCE; //private Object ... //构造器 SingleFour() { } //自定义操作 public Object operation(){ return "object"; } }
-------------------------------------------------------------