实战小技巧6:枚举的特殊用法

本文涉及的产品
对象存储 OSS,20GB 3个月
对象存储 OSS,恶意文件检测 1000次 1年
对象存储 OSS,内容安全 1000次 1年
简介: 难道我们日常使用的枚举还有什么特殊的玩法不成?没错,还真有,本文主要介绍枚举的两种不那么常见的使用姿势

难道我们日常使用的枚举还有什么特殊的玩法不成?没错,还真有,本文主要介绍枚举的两种不那么常见的使用姿势


  • 利用枚举来实现单例模式
  • 利用枚举来实现策略模式


1. 单例模式




单例模式可以说是每个 java 开发者必须掌握的一个设计模式了,通常我们说它的实现,有饱汉式和饿汉式,也有经常说的双重判断,今天我们介绍另外一种方式,借助枚举来实现


public enum SingleEnum {
    INSTANCE;
    public void print(String word) {
        System.out.println(word);
    }
}
@Test
public void testSingle() {
    SingleEnum.INSTANCE.print("hello world");
}
复制代码


使用枚举来实现单例模式非常非常简单,将类声明为枚举,内部只定义一个值即可

为什么可以这样做?


  • 枚举类不能new,因此保证单例
  • 枚举类不能被继承
  • 类不加载时,不会实例化


使用枚举类创建的单例有一个好处,就是即使用反射,也无法打破它的单例性质,这是相比较于其他的实现方式的一个优点


那么,为啥在实际的项目中,不太常见这种写法?


  • 就我个人的一点认知(不保证准确):这个与我们对枚举的认知有一定关系,在 《Effect in java》一书中,推荐我们使用这种方式来实现单例,但是在实际的项目开发中,我们更多的将枚举作为常量来使用,很少在枚举类中,添加复杂的业务逻辑


2. 策略模式



枚举除了很容易就实现上面的单例模式之外,还可以非常简单的实现策略模式

举一个简单的例子,我现在有一个接口,通过接受的参数,来决定最终的数据存在什么地方


如果按照正常的写法,可能就是很多的 if/else

public void save(String type, Object data) {
    if ("db".equals(type) {
        // 保存到db
        saveInDb(data);
    } else if ("file".equals(type))
        // 保存在文件
        saveInFile(data);
    } else if ("oss".eqauls(type)) {
        // 保存在oss
        saveInOss(type);
    }
}
复制代码


上面这种写法虽说简单直观,但是当 type 类型一多了之后,这个 if/else 的代码行数就会很多很多了,而且看起来也不美观


接下来我们介绍一种利用枚举,基于策略模式的思想来解决上面的 if/else 问题

public enum SaveStrategyEnum {
    DB("db") {
        @Override
        public void save(Object obj) {
            System.out.println("save in db:" + obj);
        }
    },
    FILE("file") {
        @Override
        public void save(Object obj) {
            System.out.println("save in file: " + obj);
        }
    },
    OSS("oss") {
        @Override
        public void save(Object obj) {
            System.out.println("save in oss: " + obj);
        }
    };
    private String type;
    SaveStrategyEnum(String type) {
        this.type = type;
    }
    public abstract void save(Object obj);
    public static SaveStrategyEnum typeOf(String type) {
        for (SaveStrategyEnum strategyEnum: values()) {
            if (strategyEnum.type.equalsIgnoreCase(type)) {
                return strategyEnum;
            }
        }
        return null;
    }
}
public void save(String type, Object data) {
    SaveStrategyEnum strategyEnum = SaveStrategyEnum.typeOf(type);
    if (strategyEnum != null) {
        strategyEnum.save(data);
    }
}
复制代码


上面的实现,主要利用的是抽象类 + 枚举来完成不同的策略具体实现


这种实现方式,相比较与前面的单例模式,还是更常见一点,虽然整体看下来没有什么难度,但是仔细看一看,会发现几个知识点


  • 抽象方法的使用 (在模板设计模式中,更能体会抽象方法的使用妙处)
  • 利用枚举原生提供的values(),来实现遍历,找到目标


3. 小结



枚举虽然说是 jdk 原生提供的一个基础数据类型,但是它的使用姿势除了我们熟知的常量之外,还可以有效的运用在设计模式中,让我们的代码实现更优雅


比如使用枚举来实现单例模式,就不用再面对让人烦躁的双重判断/内部类的方式了

使用枚举的策略模式,也可以有效解决我们类中大量的 if/else




相关实践学习
借助OSS搭建在线教育视频课程分享网站
本教程介绍如何基于云服务器ECS和对象存储OSS,搭建一个在线教育视频课程分享网站。
相关文章
|
7月前
|
存储 编译器 Shell
【C++基础语法 枚举】解析 C/C++ 中枚举类型大小值
【C++基础语法 枚举】解析 C/C++ 中枚举类型大小值
87 0
|
7月前
|
C语言
C 语言中布尔值的用法和案例解析
在编程中,您经常需要一种只能有两个值的数据类型,例如: - 是/否 - 开/关 - 真/假 为此,C语言有一个 `bool` 数据类型,称为布尔值。
236 1
|
6月前
枚举基础知识
枚举基础知识
34 0
|
7月前
|
Java
JavaSE基础篇:枚举的高级用法示例
JavaSE基础篇:枚举的高级用法示例
|
存储 安全 Java
枚举的 7 种使用方法
枚举的 7 种使用方法
110 0
数组的解释及使用方法
数组的解释及使用方法
87 0
C语言——enum枚举实例、知识点。使用枚举,减少相同定义步骤,简洁数据1.1.5
枚举是C语言常见的一种基本数据类型,它可以避免多个整数定义的麻烦,使代码整洁干净易读如此一看,就觉得繁琐无比,大量重复#define xx明显增加代码量,且数值需自己一一对应而枚举,可以解决这种定义连续数值的过程当变量第一个值未自定义时,第一个枚举成员的默认值则为整型0,后续成员值依次加1,如此时MON=0,TUE=1,WED=2·····.........
C语言——enum枚举实例、知识点。使用枚举,减少相同定义步骤,简洁数据1.1.5
枚举的简单使用以及案例
枚举的简单使用以及案例
93 0
枚举的简单使用以及案例
变量高级用法
变量高级用法
74 0