Java——单例设计模式
Java中有几个重要的设计模式,工厂设计模式、代理设计模式、单例设计模式,前几个在之前的博客中讲解过基本程序套路,本次讲解单例设计模式。
1、单例设计模式
现在有这样一个类,非常简单,只是当个引子。
class Singleton{
public void print(){
System.out.println("hello");
}
}
此时SingleIton存在一个无参构造方法,因为自动生成的。构造方法一般是使用public声明,但是也可以使用private声明。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Singleton inst = new Singleton();
inst.print();
}
}
class Singleton{
private Singleton() { //构造方法私有了
}
public void print(){
System.out.println("hello");
}
}
以上代码是错误的,因为此时构造方法被私有化了,无法从外部进行构造方法 的调用。现在要求构造方法、print()方法不修改的前提下,通过一些适当的SingleIton变化让外部类可以得到SingleIton类的实例化对象,并且调用print()方法。分析如下:
分析一:程序构造方法使用了private,对于private的特点,只能够在本类中进行访问,那么可以在本类中准备一个实例化对象。
class Singleton{
Singleton instance = new Singleton();
private Singleton() { //构造方法私有了
}
public void print(){
System.out.println("hello");
}
}
分析二:此时内部声明的instance为普通属性,其只有在实例化对象后可以调用,目前外部无法实例化对象,所以可以使用static,其不受实例化对象的影响。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Singleton inst = null;
inst = Singleton.instance;
inst.print();
}
}
class Singleton{
static Singleton instance = new Singleton();
private Singleton() { //构造方法私有了
}
public void print(){
System.out.println("hello");
}
}
分析三:根据我们前面所学,只要是类中出现的属性,就必须使用private进行封装,以上代码中的instance属性需要进行封装,但是封装后,就必须通过方法访问,此时需要访问的static属性,并且类无法直接在外部产生实例化对象,所以可以再编写一个static方法。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Singleton inst = null;
inst = Singleton.getInstance();
inst.print();
}
}
class Singleton{
private static Singleton instance = new Singleton();
private Singleton() { //构造方法私有了
}
public static Singleton getInstance(){
return instance;
}
public void print(){
System.out.println("hello");
}
}
分析四:以上代码很繁杂,最终目的实际上就是外部使用实例化对象调用方法,那么这种设计的意义是什么?
Singleton instA = null;
Singleton instB = null;
Singleton instC = null;
instA = Singleton.getInstance();
instB = Singleton.getInstance();
instC = Singleton.getInstance();
instA.print();
以上代码中实例化了三个对象,我们进行内存关系分析:
不管外部有多少个对象声明,最终所能产生的实例化对象只有一个。本程序限制了实例化对象的产生,只维持了一个。
分析五:代码存在缺陷
为了包装整个代码操作过程中,只有唯一的一个实例化对象,且不可更改,可以使用final声明:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Singleton instA = null;
instA = Singleton.getInstance();
instA.print();
}
}
class Singleton{
private static final Singleton INSTANCE = new Singleton();
private Singleton() { //构造方法私有了
}
public static Singleton getInstance(){
return INSTANCE;
}
public void print(){
System.out.println("hello");
}
}
以上就是单例设计模式,程序的主要特点:构造方法私有化,外部无法产生新的实例化对象,只能通过类提供的static方法,取得唯一一个对象的引用。
对于单例设计模式,有两类,饿汉式(以上代码就是)、懒汉式。
- 饿汉式:无论程序中是否有对象需要使用此类,此类对象都要实例化好;
- 懒汉式:在第一次使用的时候才进行实例化。
【举例】:观察懒汉式
class Singleton{
private static Singleton instance;
private Singleton() { //构造方法私有了
}
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton(); //需要的时候进行实例化
}
return instance;
}
public void print(){
System.out.println("hello");
}
}
这两个分类只是一个小概念,关键还是将之前的单例设计模式编写熟练。
2、多例设计模式
本质一样,构造方法私有化,内部产生实例化对象,只不过单例设计模式只产生一个,多例设计模式可以产生有限的多个。例如:描述性别的类,只能有两个。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Sex sex = Sex.getInstance(Sex.MALE_CH);
System.out.println(sex);
}
}
class Sex{
public static final int MALE_CH =1;
public static final int FEMALE_CH =2;
private static final Sex MALE = new Sex("男");
private static final Sex FEMALE = new Sex("女");
private String title;
private Sex(String title) {
this.title = title;
}
public static Sex getInstance(int ch){
switch (ch){
case MALE_CH:
return MALE;
case FEMALE_CH:
return FEMALE;
default:
return null;
}
}
public String toString(){
return this.title;
}
}
多例设计模式只是单例设计模式的衍生,本质上没有区别。
3、总结
1)对于单例设计模式、多例设计模式,需要理解设计的出发点:限制对象的产生;
2)程序的基本结构必须记住,与开发 理解结构设计直接联系,很重要。
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- C# 通过T4自动生成代码
- Netty 主从多线程
- 斐波那契数组-递归和循环实现
- KMP算法 C#实现 字符串查找简单实现
- elasticsearch压力测试工具之ESrally使用说明
- BitMap算法 .net实现 用于去重并且排序,适用于大型权限管理 ,大数据去重排序
- 5.FFMPEG-Qt移植ffmpeg、ffmpeg结构体介绍
- winform总结6=>线程和委托的关系
- winform总结3> 有趣的bat/winform程序完成自己的任务,然后把自己删除
- winform总结2> Action<> ,Action,func<>,委托相关的理解
- winform开发 总结1>winform程序使用线程的必要性,以及正确的使用方式
- Winform 后台将指定的控件集合添加到制定容器中
- C#微信公众平台接入示例代码
- FreeRTOS三种数据结构区别(StreamBuffer,MessageBuffer,Queue)
- Keras & Tensorflow 笔记