浅析Java设计模式编程中的单例模式和简单工厂模式
作者:lixiang0522 发布时间:2021-10-13 15:27:54
单例模式
动机
有时候只有一个类的实例是很重要的。比如,一个系统应该只有一个窗口管理实例。
单例模式是最简单设计模式:类负责实例化自己,确保只有一个实例,并且提供一个访问这个实例的入口。
目的
1. 确保只有一个实例被创建。
2. 提供访问这个实例的入口。
使用final确保被创建一次,private的构造函数确保不被实例化。public的getInstance方法确保外部能够访问。下面是饿汉模式:
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
懒汉模式:
public class SingletonDemo {
private static volatile SingletonDemo instance = null;
private SingletonDemo() { }
public static SingletonDemo getInstance() {
if (instance == null) {
synchronized (SingletonDemo .class){
if (instance == null) {
instance = new SingletonDemo ();
}
}
}
return instance;
}
}
适用场景和实例
1. Logger类,防止每次打印log的使用都创建一个Logger实例。
2. 控制类,一般整个系统都只有一个控制实例。
具体问题和实现
1. 线程安全,健壮的单例模式应该是线程安全的。
2. 懒汉模式使用了双重锁机制。
3. 饿汉模式使用静态变量,在程序加载时就实例化,保证了只有一个实例。
4. 抽象工厂和工厂方法通常被设计成单例模式,以保证只有一个工厂。
5. 使用序列化和反序列化时,会有多个实例被创建,使用readResolve函数避免这个情况,不过最好是不要使用序列化。
public class Singleton implements Serializable {
...
// This method is called immediately after an object of this class is deserialized.
// This method returns the singleton instance.
protected Object readResolve() {
return getInstance();
}
}
关键点
1. 在多线程的程序中,要注意数据的同步。
2. 序列化时要使用readResolve方法返回实例,避免多个对象被创建。
3. 如果被多个类加载器加载时,会有多个实例被创建。
简单工厂模式
动机
简单工厂模式是抽象工厂和工厂方法的基础和初步实现。
目的
1. 不向客户透露对象实例化的细节。
2. 通过通用接口创建对象。
实现
实现非常简单:
1. Client需要Product时,不使用new来创建,而是提供 Product 描述给Factory,让 Factory 提供一个新的 Product 。
2. Factory实例化一个Product给Client。
3. Client使用抽象Product,而不关心Product的具体实现。
实例
1. 绘制形状的绘图程序。形状就是Product接口,三角形这些是Concrete Product,我们可以创建一个工厂,然后根据客户的描述创建对于的产品。不过添加新的形状时,我们需要修改工厂类。
具体问题和实现
1. 添加新产品时,需要修改工厂。
public class ProductFactory{
public Product createProduct(String ProductID){
if (id==ID1)
return new OneProduct();
if (id==ID2)
return new AnotherProduct();
... // so on for the other Ids
return null; //if the id doesn't have any of the expected values
}
...
}
一般我们通过if语句判断产品描述,并实例化不同的产品,有新的产品时,我们需要增加新的判断。通过抽象工厂模式可以解决这个问题。
总结
1. 当你确实需要工厂模式时才使用,不然只是增加程序的复杂度,比如多种对象有相似的基本类型时,可以考虑使用简单工厂模式来统一创建对象。
2. 简单工厂有比较多的判断分支语句,违反了开闭原则的对修改关闭的原则,所以,明智的做法是,对一些固定和简单程序使用简单工厂模式,对一些复杂和需要经常扩展的程序,使用抽象工厂模式或者工厂方法模式。


猜你喜欢
- Mybatis表现关联关系比hibernate简单,没有分那么细致one-to-many、many-to-one、one-to-one。而是
- 本文实例讲述了C#实现的算24点游戏算法。分享给大家供大家参考。具体如下:using System;using System.Collect
- 通过Class对象获取对象的方式是通过class.newInstance()方式获取,通过调用默认构造参数实例化一个对象。/** * Cre
- 一个简单的拼图小游戏,供大家参考,具体内容如下1.首先设计视图面板。2.添加所需要的图片按钮。3.最主要的是设计监听事件,添加图片的监听按钮
- 如图所示为程序效果动画图地图滚动的原理在本人之前博客的文章中介绍过人物在屏幕中的移动方式,因为之前拼的游戏地图是完全填充整个手机屏幕的,所以
- 前言项目中时不时遇到查字典表等数据,只需要返回数据,不需要写其他业务,每个字典表可能都需要写一个接口给前端调用,比较麻烦,所以采用下面这种方
- 1 顺序结构顺序结构比较简单,就是代码一行一行的执行,本节之前写的所有代码都是顺序结构。例如:public static void main
- 在代码中进行命令行交互是一个很常见的场景, 特别是在一些CI CD 自动化流程中, 在这之前我们会使用 System.Diagnostics
- 首先演示下效果,分段选择按钮,支持点击和滑动切换。视图绘制过程中,要执行onMeasure、onLayout、onDraw等方法,这也是自定
- 缓冲区的建立目的就是增加传输性能,使我们传输数据更加快速缓冲区的内部其实很简单 就是在内部封装了一个数组 用数组来存储数据 对外提供一些方法
- SpringBoot配置文件的替换使用spring.profiles.active在工作中,测试或上线的时候一定会遇到的问题就是修改配置。一
- 最近我在考虑如何远程控制tomcat的启动和关机,最后是有友好的界面,能够实现一键式操作的,这样会肯定是会很方便的,网上找了半天,没找到,有
- 实践过程效果代码public partial class Form1 : Form{ public Form1()
- 本文实例讲述了Android使用WebView.loadUri()打开网页的方法。分享给大家供大家参考,具体如下:程序如下所示:import
- Class.forName(xxx.xx.xx) 返回的是一个类一.首先你要明白在java里面任何class都要装载在虚拟机上才能运行。1.
- 在html中大家都知道布局是什么意思了,简单来说就是将页面划分模块,比如html中的div、table等。那么Android中也是这样的。A
- 0x01 新建SpringBoot项目1. 新建maven工程ps:在上一教程的基础上操作,就不用新建项目了,请参考文章:SpringBoo
- 导读本文主体为单项链表和双向链表的反转以及简单的测试,以便于理解链表相关的算法题目。链表特点便于增删数据,不便于寻址在内存中属于跳转结构单链
- 1、spring原理内部最核心的就是IOC了,动态注入,让一个对象的创建不用new了,可以自动的生产,这其实就是利用java里的反射,反射其
- java中对List分段操作的实例问题:假设A系统查询出来一个很大很大的List,现在B系统想要得到这个List来导出报表,但是B系统部署环