在我们平时的工作学习中,代码的整洁与高可用会让程序更加有效率,对项目的好处不言而喻。
设计模式的学习会让我们的编程水平得到很大的提升,同时也有助于对框架的理解,因为优秀的框架结构都用到了设计模式。
今天先瞅瞅单例模式,剩余的设计模式我也会慢慢更新,做一个系列。
设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。 是对面向对象设计中反复出现的问题的解决方案
使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。
Java设计模式贯彻的原理是:面向接口编程,而不是面向实现。其目标的原则是:降低耦合,增强灵活性。
创建型模式是用来创建对象的模式,抽象了实例化的过程,帮助一个系统独立于其关联对象的创建、组合和表示方式。
所有的创建型模式都有两个主要功能:
常见的创建型模式:
结构型模式讨论的是类和对象的结构,它采用继承机制来组合接口或实现(类结构型模式),或者通过组合一些对象实现新的功能(对象结构型模式)。
常见结构型模式:
行为型模式关注的是对象的行为,用来解决对象之间的联系问题。
常见行为型模式:
定义:Ensure a class has only one instance, and provide a global Point of access to it.
确保一个类只有一个实例存在。
最好学习方法就是分析代码:
/**
* 饿汉式(类加载时,就进行对象实例化)
* 类加载到内存后,就实例化一个单例,JVM保证线程安全
* 类只加载一次,实例化一次 Class.forName()
* 缺点:类完成加载,就完成实例化
*/
public class Manager01 {
//private确保构造方法无法被外界实例化
private Manager01(){
}
//静态常量(或变量)
private static final Manager01 INSTANCE = new Manager01();
//通过该方法获得实例
public static Manager01 getInstance(){
return INSTANCE;
}
//其余业务方法
public void useOthers(){
}
public static void main(String[] args) {
Manager01 instance1 = Manager01.getInstance();
Manager01 instance2 = Manager01.getInstance();
//输出结果为True,同一个对象
System.out.println(instance1==instance2);
}
}
/**
* 懒汉式(第一次引用类时,才进行对象实例化)
* Lazy Loading
* 按需初始化,但要保证多线程并发安全
*/
public class Manager02 {
private Manager02(){}
private static Manager02 INSTANCE;
public static Manager02 getInstance(){
//public static synchronized Manager02 getInstance()
//加锁亦可在方法上,保证同步,多线程容易发生创建多个实例
synchronized (Manager02.class){
//判断是否已实例化
if (INSTANCE==null){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
INSTANCE = new Manager02();
}
return INSTANCE;
}
}
//业务方法等
public void useOthers(){}
public static void main(String[] args) {
//创建100个线程,结果只有一个实例被创建
for (int i = 0; i < 100; i++) {
//lambda表达式
new Thread(()->{
System.out.println(Manager02.getInstance().hashCode());
}).start();
}
}
}
懒汉式模式会加锁,导致效率降低,双重模式是对懒汉的优化
/**
* 双重判断
*/
public class Manager03 {
private Manager03(){}
private static Manager03 instance;
public static Manager03 getInstance(){
//判断第一次,若实例已存在,直接跳转返回instance。无需等待锁的释放
if (instance==null){
synchronized (Manager03.class){
//二次判断,若此时已存在实例,就跳过if块
if (instance==null){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
instance = new Manager03();
return instance;
}
}
}
return instance;
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(()->{
System.out.println(Manager03.getInstance().hashCode());
}).start();
}
}
}
/**
* 静态内部类
* 加载外部类时不会加载内部类,懒加载
*/
public class Manager04 {
private Manager04(){}
private static class managerHolder {
private final static Manager04 INSTANCE = new Manager04();
}
public static Manager04 getInstance(){
return managerHolder.INSTANCE;
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(()->{
System.out.println(Manager04.getInstance().hashCode());
}).start();
}
}
}
/**
* 枚举单例
* 大佬写的,不仅解决线程同步,还可以反序列化
* 完美
*/
public enum Manager05 {
INSTANCE;
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(()->{
System.out.println(Manager05.INSTANCE.hashCode());
}).start();
}
}
}
最常用最简单的就是饿汉式,懒汉式了。
上面示例为看视频总结手敲,很精妙
本文转载自微信公众号「小林coding」,作者木叶潇潇。转载本文请联系小林coding...
本文实例讲述了PHP程序员简单的开展服务治理架构操作。分享给大家供大家参考,具...
本文实例为大家分享了VS2012实现登录界面的具体代码,供大家参考,具体内容如下 ...
三维空间刚体运动4-4四元数线性插值方法Spring-1 1. 总述多点旋转插值的数学方法...
YXcms(MVC) YXcms 1.4.7 熟悉MVC架构 路由方式 通过一个 r 的文件指针进行路由 ...
1、首先是如果你遇到javax.servlet.ServletException: java.lang.ClassNotFoundE...
MySQL的binlog相信大家都有所耳闻,但是可能没有真正日常使用过。 因此,本文结...
西部世界特撰此文旨在分析Filecoin现阶段的机遇以及未来该如何布局且看以下内容 ...
前言 大家应该都知道,对于传统的.NET Framework项目而言, System.Runtime.Cach...
【平台】 在线HTML编辑器:eWebEditor Version 2.8.0 最终版 网页浏览器:Google...