单例(Singleton)模式

为了节省内存资源、保证数据内容的一致性,对某些类要求只能创建一个实例,这就是所谓的单例模式。

单例模式的定义:一个类只能有一个实例,且该类能自行创建这个实例的一种模式。
单例模式的特点

  1. 单例类只能有一个实例对象;
  2. 该单例对象必须由单例类自行创建;
  3. 单例类对外提供一个访问该单例的全局访问点;

单例模式的实现原理:单例模式是设计模式中最基础的模式之一。通常一个普通类的构造方法是公有方法,外部类可以通过new构造方法来生成很多的实例。但是如果将构造函数设为私有方法,外部类就无法调用该构造方法,也就无法生成多个实例。该类必须定义一个静态私有实例,并且向外提供一个静态的公有函数用于创建或获取该静态私有实例。

单例模式的实现
单例模式通常有俩种实现形式:

  1. 懒汉模式
    这个模式下的特点是,只有当第一次调用getInstance方法的时候,才会创建这个单例。
public class Singleton {private static volatile Singletoninstance = null;//保证instance在线程中同步private Singleton() {//私有化构造方法避免被外部调用}public static synchronized Singleton getInstance() {//getInstance方法前加同步if(instance == null) {instance = new Singleton();}return instance;}
}

如果编写的是多线程程序,则不要删除上例代码中的关键字 volatile 和 synchronized,否则将存在线程非安全的问题。如果不删除这两个关键字就能保证线程安全,但是每次访问时都要同步,会影响性能,且消耗更多的资源,这是懒汉式单例的缺点。

  1. 饿汉模式
    该模式的特点是类一旦加载就创建一个单例,保证在调用 getInstance 方法之前单例已经存在了
public class Singleton {private static final Singleton instance = new Singleton();//类被加载后就创建一个单例private Singleton() {}public static Singleton getInstance() {return instance;}
}

饿汉式单例在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以是线程安全的,可以直接用于多线程而不会出现问题。

工厂(Factory)模式

工厂模式主要是为创建对象提供了接口。工厂模式按照《Java与模式》中的提法分为三类:

  1. 简单工厂模式(Simple Factory)
  2. 工厂方法模式(Factory Method)
  3. 抽象工厂模式(Abstract Factory)
简单工厂模式:

这个模式本身很简单,而且使用在业务较简单的情况下,它由三种角色组成:

  1. 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现。
  2. 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。
  3. 具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。
例子:

抽象产品角色:

public interface Car {//车可以跑起来void run();//车可以加油void addOil();
}

具体产品角色类:

public class BmwCar implements Car{@Overridepublic void run() {System.out.println("开宝马");}@Overridepublic void addOil() {System.out.println("加柴油");}
}
public class BenzCar implements Car{@Overridepublic void run() {System.out.println("开奔驰");}@Overridepublic void addOil() {System.out.println("加汽油");}
}

工厂类角色类:

public class CarSimpleFactory {public static Car createCar(String type) {Car car = null;if("Benz".equals(type)) {car = new BenzCar();}else if("Bwm".equals(type)){car = new BmwCar();}return car;}
}

测试:

public class Test {public static void main(String[] args) {Car car = CarSimpleFactory.createCar("Benz");car.run();car.addOil();}
}

上面的简单工厂虽然用法简单,但不利于扩展。当我们新增一种新车型时,我们需要修改简单工厂的代码,这不符合开闭原则,而且当
简单工厂创建的对象经常改变,种类繁多时,也就不符合单一职责。

工厂模式:

在工厂模式里,创建了更多的对象,拆分了功能,使其职能单一,并且符合开闭原则,但是让系统代码结构更加复杂化,其组成如下:

  1. 抽象工厂角色:这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
  2. 具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在java中它由具体的类来实现。
  3. 抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
  4. 具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。

抽象工厂角色类:

public interface CarFactory {Car CreateInstance();
}

具体工厂角色类:

public class BenzCarFactroy implements CarFactory{@Overridepublic Car CreateInstance() {return new BenzCar();}
}
public class BmwCarFactory implements CarFactory{@Overridepublic Car CreateInstance() {return new BmwCar();}
}

抽象产品角色类:

public interface Car {//车可以跑起来void run();//车可以加油void addOil();
}

具体产品角色类:

public class BenzCar implements Car{@Overridepublic void run() {System.out.println("开奔驰");}@Overridepublic void addOil() {System.out.println("加汽油");}
}
public class BmwCar implements Car{@Overridepublic void run() {System.out.println("开宝马");}@Overridepublic void addOil() {System.out.println("加柴油");}
}

测试:

public class Test2 {public static void main(String[] args) {CarFactory carFactory = new BenzCarFactroy();Car car = carFactory.CreateInstance();car.addOil();car.run();}
}
抽象工厂模式:

抽象工厂模式(Abstract Factory)是一个比较复杂的创建型模式。

抽象工厂模式和工厂方法不太一样,它要解决的问题比较复杂,不但工厂是抽象的,产品是抽象的,而且有多个产品需要创建,因此,这个抽象工厂会对应到多个实际工厂,每个实际工厂负责创建多个实际产品。

抽象产品角色类:

public interface ICar {//轿车void roadPeople();
}
public interface ITruck {//卡车void roadGood();
}
public interface IVan {//货车void roadShipment();
}

抽象工厂:

public abstract class AbstractFactory {//抽象工厂protected abstract ICar createCar();protected abstract ITruck createTruck();protected abstract IVan creatVan();
}

具体产品角色类:

public class BmwCar implements ICar{@Overridepublic void roadPeople() {System.out.println("宝马轿车"); }
}
public class BmwTruck implements ITruck{@Overridepublic void roadGood() {System.out.println("宝马卡车"); }
}
public class BmwVan implements IVan{@Overridepublic void roadShipment() {System.out.println("宝马货车"); }
}

具体工厂角色类:

public class BmwFactory extends AbstractFactory{//宝马工厂@Overrideprotected ICar createCar() {return new BmwCar();}@Overrideprotected ITruck createTruck() {return new BmwTruck();}@Overrideprotected IVan creatVan() {return new BmwVan();}
}

测试:

public class Test {public static void main(String[] args) {AbstractFactory factory = new BmwFactory();factory.createTruck().roadGood();}
}

抽象工厂模式结构较复杂,理解难度大,当工厂新增一个产品时,需要修改工厂的方法,不符合开闭原则。

代理模式

策略模式

模板方法模式

观察者模式

适配器模式

责任键模式

建造者模式

【设计模式】常用9种设计模式详解相关推荐

  1. 工厂设计模式(三种)详解

    什么是工厂设计模式? 工厂设计模式,顾名思义,就是用来生产对象的,在java中,万物皆对象,这些对象都需要创建,如果创建的时候直接new该对象,就会对该对象耦合严重,假如我们要更换对象,所有new对象 ...

  2. 走穿java23种设计模式-15责任链模式详解

    走穿java23种设计模式-15责任链模式详解 责任链模式是一种常见的行为模式. 一.责任链模式的现实场景 习伟过生日邀请了很多朋友到KTV一起庆祝,为了增加欢乐的气氛,习伟建议大家一起玩击鼓传花的游 ...

  3. 走穿java23种设计模式--18中介者模式详解

    走穿java23种设计模式–18中介者模式详解 中介者模式也称调停者模式,是一种比较简单的模式. 一.中介者模式的现实场景 蔡良因为上次表白时对方只看重他的物质方面,所以他对女朋友这个问题有点失望.因 ...

  4. 设计模式之享元模式详解

    设计模式之享元模式详解 概述 享元模式定义: ​ 运用共享技术来有效地支持大量细粒度对象的复用.它==通过共享已经存在的对象来大幅度减少需要创建的对象数量==.避免大量相似对象的开销,从而提高系统资源 ...

  5. 设计模式之装饰器模式详解

    设计模式之装饰器模式详解 文章目录 设计模式之装饰器模式详解 一.什么是装饰器模式 二.装饰器模式的角色组成 三.装饰器模式通用写法示例 四.装饰器模式业务中的应用举例 五.装饰器模式优缺点 一.什么 ...

  6. 并发编程-04线程安全性之原子性Atomic包的4种类型详解

    文章目录 线程安全性文章索引 脑图 概述 原子更新基本类型 Demo AtomicBoolean 场景举例 原子更新数组 Demo 原子更新引用类型 Demo 原子更新字段类型 使用注意事项: Dem ...

  7. kinux查日志_Linux实时查看日志的四种命令详解

    原标题:Linux实时查看日志的四种命令详解 如何在Linux中实时查看日志文件的内容?那么有很多实用程序可以帮助用户在文件更改或不断更新时输出文件的内容.在Linux中实时显示文件内容的常用命令是t ...

  8. python process 函数_Python Process创建进程的2种方法详解

    前面介绍了使用 os.fork() 函数实现多进程编程,该方法最明显的缺陷就是不适用于 Windows 系统.本节将介绍一种支持 Python 在 Windows 平台上创建新进程的方法. Pytho ...

  9. Keras深度学习实战(4)——深度学习中常用激活函数和损失函数详解

    Keras深度学习实战(4)--深度学习中常用激活函数和损失函数详解 常用激活函数 Sigmoid 激活函数 Tanh 激活函数 ReLU 激活函数 线性激活函数 Softmax 激活函数 损失函数 ...

  10. docker实践(2)常用命令和DockerFile详解

    <docker实践(1) 入门和springBoot实践部署> <docker实践(2)常用命令和DockerFile详解> <docker实践(3) 仓库registr ...

最新文章

  1. 算法---------路径总和
  2. 金蝶云如何html5登录,第三方系统单点登录到金蝶云指南V2
  3. Hdu 2522 hash
  4. iOS Safari 中click点击事件失效的解决办法
  5. linux由哪些部分组成,linux内核处于什么位置?,为你介绍一些Linux操作系统的基础知识(一)...
  6. svg圆弧进度条demo
  7. 瓦片地图与geoserver发布
  8. 入门讲解:使用numpy实现简单的神经网络(BP算法)
  9. sparksql 操作hive_Spark SQL 物化视图原理与实践
  10. 给P40让路!华为Mate 30 5G降至这个价,还贵吗?
  11. anaconda哪个版本是 python3.6_windows10(64位)Anaconda3+Python3.6搭建Tensorflow(cpu版本)及keras...
  12. (前端)html与css css 19、tab栏
  13. CSS 如何影响浏览器元素在文档中的排列?
  14. 【DEF CON】数十亿物联网设备受严重随机数生成器缺陷影响
  15. 2021荣耀秋招笔试代码题
  16. jbpm5.4 mysql_5.BDF2-JBPM4
  17. 计算机主机接电视机,电脑主机连接电视方法介绍 电脑主机连接电视注意事项...
  18. Leetcode——237. 删除链表中的节点(Java)
  19. Kali Linux Web 渗透测试秘籍 第七章 高级利用
  20. 录屏手机html5插件,越狱插件:首款能在iOS10上轻松录屏的工具!

热门文章

  1. polymer ajax_使用Polymer创建自定义音频播放器元素
  2. 使用内存映射开发高性能进程间消息通信组件
  3. Java迷宫版 吃豆人(有音乐)
  4. 阿里云服务器无法访问
  5. 天翼云盘php插件,2019-4-1 天翼云盘(家庭云)模拟提速设置方法分享(已失效)
  6. 影驰gtx960 2g
  7. 得推二手商城系统类似咸鱼商城PHP商城系统源码 v1.2
  8. custom-lib-path、engine-create的作用及如何使用他们parse-bbox(dete)deepstream-test1解析yolov5的engine引擎文件需要解析网络库(精)
  9. 北京规定京籍毕业生可利用住宅经商
  10. bilibili(b站)升级到BV号了,还想用av号怎么办?