单例设计模式&枚举

1,单例设计模式
1.1 设计模式
软件设计模式(Software Design Pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。它描述了在软件设计过程中的一些不断重复发生的问题,以及该问题的解决方案。也就是说,它是解决特定问题的一系列套路,是前辈们的代码设计经验的总结,具有一定的普遍性,可以反复使用。
1.2 单例设计模式
使一个类只能创建一个对象
1.3 单例设计模式分类
饿汉式
懒汉式
1.4 饿汉式
public class Singleton {

//1,私有构造方法
private Singleton() {}

//2,在本类中创建一个对象,供外界获取
private static Singleton instance = new Sinleton();

//3,对外提供公共的访问方式
public static Singleton getInstance() {
return instance;
}
}
1.5 懒汉式
public class Singleton {

//1,私有构造方法
private Singleton() {}

//2,在本类中创建一个对象,供外界获取
private static Singleton instance;

//3,对外提供公共的访问方式
public static Singleton getInstance() {
synchronized(Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
return instance;
}
}
提供一种简便的方式实现单例:
public class Singleton {

//1,私有构造方法
private Singleton() {}

//2,在本类中创建一个对象,供外界获取
public static final Singleton instance = new Singleton();
}
思考:如果想让一个类只能创建两个对象呢? 只能创建三个对象呢? 只能创建四个对象呢?
1,定义一个类(TwoInstance),使其只能创建一个对象
public class TwoInstance {

//1,私有构造方法
private TwoInstance() {}

//2,在本类中创建一个对象,供外界获取
public static final TwoInstance ONE = new TwoInstance();

public static final TwoInstance TWO = new TwoInstance();

}
2,定义一个类(ThreeInstance),使其只能创建三个对象
public class ThreeInstance {

//1,私有构造方法
private ThreeInstance() {}

//2,在本类中创建一个对象,供外界获取
public static final ThreeInstance ONE = new ThreeInstance();

public static final ThreeInstance TWO = new ThreeInstance();

public static final ThreeInstance THREE = new ThreeInstance();

}
2,枚举
上面使一个类只能创建指定个对象的方式有点麻烦,看下面代码也可以实现同样的效果:
public enum TwoInstance {
ONE,TWO
}
public enum ThreeInstance {
ONE,TWO,THREE
}
通过改写我们可以看到简单了很多。那么,上面定义的到底是什么?
2.1 什么是枚举
enum就是JDK1.5后定义的枚举。枚举本质就是只能创建指定个对象的类。
2.2 证明枚举本质就是类
//类,可以定义构造方法,成员变量,成员方法
public class TwoInstance {

//定义有参构造方法
private TwoInstance(int i) {}

//定义成员变量
public String name = “robin”;

public static final TwoInstance ONE = new TwoInstance(10);

public static final TwoInstance TWO = new TwoInstance(20);

//定义成员方法
public void show() {
System.out.println(“show”);
}
}

//枚举,也可以定义构造方法,成员变量,成员方法
public enum TwoInstance {
ONE(10),TWO(20);
public TwoInstance(int i) {}

private String name = “robin”;

//定义成员方法
public void show() {
System.out.println(“show”);
}
}
在测试类中测试一下枚举,看能不能调用成员变量,成员方法
public class Demo {
public static void main(String[] args) {
TwoInstance instance = TwoInstance.ONE;
instance.name = “张三”;
System.out.println(instance.name);

    instance.show();

    System.out.println("------------");
    TwoInstance instance1 = TwoInstance.TWO;
    instance1.name = "李四";
    System.out.println(instance1.name);

    instance1.show();
}

}

注意:以后开发中不会给枚举中定义构造方法,成员方法,成员变量!!!!!
2.2 使用场景
需求: 在WeekUtil类中定义一个静态方法,给定指定的参数输出对应的星期
public class WeekDemo {
public static void main(String[] args) {
printWeek(1);
}
}

public class WeekUtil {

public static void printWeek(int week) {
    switch (week) {
        case 1:
            System.out.println("星期一");
            break;
        case 2:
            System.out.println("星期二");
            break;
        case 3:
            System.out.println("星期三");
            break;
        case 4:
            System.out.println("星期四");
            break;
        case 5:
            System.out.println("星期五");
            break;
        case 6:
            System.out.println("星期六");
            break;
        case 7:
            System.out.println("星期日");
            break;
    }
}

}

经过测试可以在控制台打印星期一,如果传递的参数是2,在控制台打印的是星期二,整个效果和我们预期的一样。
但是我们在调用printWeek方法时,只知道需要的是int类型的数据,但是到底传递的是什么,需要传递什么样的数字我们并不明确,也就是没有做到见名知意呢?看下面的代码
public class WeekDemo {
public static void main(String[] args) {
WeekUtil.printWeek(WeekUtil.FRIDAY);
}
}

public class WeekUtil {

public static final int MONDAY = 1;
public static final int TUESDAY = 2;
public static final int WEDNESDAY = 3;
public static final int THURSDAY = 4;
public static final int FRIDAY = 5;
public static final int SATURDAY = 6;
public static final int SUNDAY = 7;

public static void printWeek(int week) {
    switch (week) {
        case 1:
            System.out.println("星期一");
            break;
        case 2:
            System.out.println("星期二");
            break;
        case 3:
            System.out.println("星期三");
            break;
        case 4:
            System.out.println("星期四");
            break;
        case 5:
            System.out.println("星期五");
            break;
        case 6:
            System.out.println("星期六");
            break;
        case 7:
            System.out.println("星期日");
            break;
    }
}

}

经过上面的改进,已经做到了见名知意,这样在使用起来就方便很多了。但是依然存在问题,什么问题呢?
对于使用者可以使用WeekUtil类中提供的常量,当然也可以自己随便给定一个int类型的数字,这样在控制台就不会输出任何内容,为什么呢?printWeek方法只需要的是1-7之间的正数,而使用者传递的是其他的数字。那么怎么样才能不让使用者传递一些不合法的参数值呢?这个就需要用到枚举
public enum Week {
MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY
}

public class WeekUtil {

public static void printWeek(Week week) {
    switch (week) {
        case MONDAY:
            System.out.println("星期一");
            break;
        case TUESDAY:
            System.out.println("星期二");
            break;
        case WEDNESDAY:
            System.out.println("星期三");
            break;
        case THURSDAY:
            System.out.println("星期四");
            break;
        case FRIDAY:
            System.out.println("星期五");
            break;
        case SATURDAY:
            System.out.println("星期六");
            break;
        case SUNDAY:
            System.out.println("星期日");
            break;
    }
}

}

public class WeekDemo {
public static void main(String[] args) {
WeekUtil.printWeek(Week.SATURDAY);
}
}

再次改进,现在大家可以想想能不能在调用printWeek方法时传递一些其他不合法的参数值,答案是不可以的。

发布了71 篇原创文章 · 获赞 1 · 访问量 1147

猜你喜欢

转载自blog.csdn.net/weixin_44993313/article/details/103796217