java1.5之后,枚举类实现单例模式
一. 单例模式
传统的懒汉式,饿汉式实现单例模式,我就不在此赘述了,直接切入主题,枚举类实现单例模式.
话不多说,直接上代码,注释很详细了.....
枚举类
package com.yfq.yfq_admin.testEnum;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
/**
* 描述:枚举,单例模式实现类(枚举第一次被调用时创建)
*
*@创建人 lv617
*@创建时间 2019/4/9 16:31
*/
public enum TestSingletonEnum {
// 此处定义了两个单例模式的实例,TestSingletonEnum枚举类被调用时,会同时初始化这两个实例;
// 不建议一个枚举类中同时定义两个单例,虽然各不影响,但是初始化会在第一次被调用时同时初始化;
SINGLETON_NUM,
SINGLETON_COUNT;
private Integer num;
TestSingletonEnum() {
this.num = 1;
System.err.println(super.name());
System.err.println(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
public Integer addNum(Integer add){
if(add == null){
this.num++;
return this.num;
}else{
this.num = this.num + add;
return this.num;
}
}
}
单元测试类
@Test
public void test6(){
System.err.println(TestSingletonEnum.SINGLETON_NUM.getNum());
TestSingletonEnum.SINGLETON_NUM.addNum(null);
System.err.println(TestSingletonEnum.SINGLETON_NUM.getNum());
TestSingletonEnum.SINGLETON_NUM.addNum(5);
System.err.println(TestSingletonEnum.SINGLETON_NUM.getNum());
System.err.println("=====================================");
System.err.println(TestSingletonEnum.SINGLETON_COUNT.getNum());
TestSingletonEnum.SINGLETON_COUNT.addNum(null);
System.err.println(TestSingletonEnum.SINGLETON_COUNT.getNum());
TestSingletonEnum.SINGLETON_COUNT.addNum(5);
System.err.println(TestSingletonEnum.SINGLETON_COUNT.getNum());
System.err.println("=====================================");
System.err.println(TestSingletonEnum.SINGLETON_NUM.getNum());
TestSingletonEnum.SINGLETON_NUM.addNum(null);
System.err.println(TestSingletonEnum.SINGLETON_NUM.getNum());
TestSingletonEnum.SINGLETON_NUM.addNum(5);
System.err.println(TestSingletonEnum.SINGLETON_NUM.getNum());
}
测试结果截图
二. 举一反三
枚举类的简单使用技巧
支付接口类
package com.yfq.yfq_admin.testEnum;
public interface TestPayService {
/**
* 描述:伪代码,支付方法
*
*@创建人 lv617
*@创建时间 2019/4/9 17:45
*/
void pay(Integer amount);
}
支付接口实现类
package com.yfq.yfq_admin.testEnum;
import org.springframework.stereotype.Service;
/**
* @ClassName:TestPayServiceImpl
* @Description:多种支付方式其中的一种支付方式的具体实现类,这里是伪代码
* @Author:lv617
* @Date:2019/4/9 15:35
* @Version:1.0
**/
@Service
public class TestPayServiceImpl implements TestPayService{
@Override
public void pay(Integer amount) {
System.err.println("伪代码支付成功,支付金额:" + amount + "-------");
}
}
订单类型与支付方式关联枚举类
package com.yfq.yfq_admin.testEnum;
/**
* @ClassName:TestOrderTypeEnum
* @Description:订单类型与支付方式关联枚举类,该枚举类使用了,抽象方法
* @Author:lv617
* @Date:2019/4/9 11:48
* @Version:1.0
**/
public enum TestOrderTypeEnum {
// 该枚举类使用了抽象方法,即getPayName()方法;
// 注:抽象方法的实现方法,是在枚举类型后边用{}实现;
// 第一种支付方式TestPayServiceImpl.class
TYZ("02","团油赚", TestPayServiceImpl.class){
@Override
public String getPayName() {
return "伪代码,我是微信支付-----";
}
},
// 第二种支付方式,这里的TestPayServiceImpl.class类应该使用其它的支付方式替换,我为了简单,再次只写一个了
CYK("03","充油卡", TestPayServiceImpl.class){
@Override
public String getPayName() {
return "伪代码,我是支付宝支付-----";
}
};
private String code;
private String name;
private Class<? extends TestPayService> payService;
TestOrderTypeEnum(String code, String name, Class<? extends TestPayService> payService) {
this.code = code;
this.name = name;
this.payService = payService;
}
public Class<? extends TestPayService> getPayService() {
return payService;
}
public void setPayService(Class<? extends TestPayService> payService) {
this.payService = payService;
}
public String getCode() {
return code;
}
public String getName() {
return name;
}
public void setCode(String code) {
this.code = code;
}
public void setName(String name) {
this.name = name;
}
/**
* 描述:根据name获取code
*
*@创建人 lv617
*@创建时间 2019/4/9 17:28
*/
public static String getCode(String name){
TestOrderTypeEnum orderTypeEnum = getOrderTypeEnumByName(name);
return orderTypeEnum==null?null:orderTypeEnum.getCode();
}
public static TestOrderTypeEnum getOrderTypeEnumByName(String name) {
TestOrderTypeEnum[] values = TestOrderTypeEnum.values();
for (TestOrderTypeEnum orderTypeEnum : values) {
if(orderTypeEnum.getName().equals(name))
return orderTypeEnum;
}
return null;
}
/**
* 描述:根据code获取name
*
*@创建人 lv617
*@创建时间 2019/4/9 17:29
*/
public static String getName(String code){
TestOrderTypeEnum[] values = TestOrderTypeEnum.values();
for (TestOrderTypeEnum orderTypeEnum : values) {
if(orderTypeEnum.getCode().equals(code))
return orderTypeEnum.getName();
}
return null;
}
public static TestOrderTypeEnum getOrderTypeEnumByCode(String code){
TestOrderTypeEnum[] values = TestOrderTypeEnum.values();
for (TestOrderTypeEnum orderTypeEnum : values) {
if(orderTypeEnum.getCode().equals(code))
return orderTypeEnum;
}
return null;
}
/**
* 描述:重写toString方法
*
*@创建人 lv617
*@创建时间 2019/4/9 17:29
*/
@Override
public String toString() {
return super.name()+"(\""+this.getCode()+"\",\""+this.getName()+"\")";
}
/**
* 描述:枚举类,抽象方法
*
*@创建人 lv617
*@创建时间 2019/4/9 17:30
*/
public abstract String getPayName();
}
单元测试类
@Test
public void test5(){
// 枚举类的简单用法
System.err.println(TestOrderTypeEnum.getCode("团油赚"));
System.err.println(TestOrderTypeEnum.getName("02"));
System.err.println(TestOrderTypeEnum.CYK.getCode());
System.err.println(TestOrderTypeEnum.CYK.getName());
System.err.println(TestOrderTypeEnum.getOrderTypeEnumByCode("02").toString());
TestOrderTypeEnum cyk = TestOrderTypeEnum.valueOf("CYK");
System.err.println(cyk.toString());
System.err.println("=====================================");
// 枚举类的升级用法(使用场景:例如订单支付时多个支付方式,可以根据type类型,获取相应的支付类)
TestOrderTypeEnum[] values = TestOrderTypeEnum.values();
for (TestOrderTypeEnum orderTypeEnum : values) {
System.err.println(orderTypeEnum.toString());
// 抽象方法调用
System.err.println(orderTypeEnum.getPayName());
// 在spring上下文中获取类,也是单例模式的一种体现;
TestPayService payService = SpringContext.getBean(orderTypeEnum.getPayService());
payService.pay(617);
}
System.err.println("=====================================");
}
测试结果截图