【单例模式、多例模式、工厂模式和枚举】

1、单例设计模式

作用:通过单例模式可以保证系统中,应用该模式的类只有一个实例。即一个对象之只能有一个实例化对象。

实现步骤

1、将类的构造方法私有化,使其在类外部不能通过new关键字来实例化该对象;
2、在该类的内部声明唯一的实例化对象;
3、定义一个静态方法返回这个唯一的实例化对象;

单例模式分类
1、饿汉单例设计模式

饿汉式单例设计模式就是不管该类的实例化对象是否后面被用到,在该类加载时就先实例化完毕。

//1. 饿汉单例设计模式
public class Person {

    //1、将构造方法私有化,外部不能通过new来实例化对象
    private Person(){ }

    //2、定义一个Person对象,不管用不用得到此对象的实例化,都先创建该对象的实例化,且唯一不可改变
    private static final Person p= new Person();

    //3、定义一个静态方法,返回这个唯一对象
    public static Person getInstance(){
        return p;
    }
}

class Test{
    public static void main(String[] args) {
        Person p1 = Person.getInstance();
        Person p2 = Person.getInstance();
        Person p3 = Person.getInstance();

        System.out.println(p1); //com.cyy.design.Person@6d6f6e28
        System.out.println(p2); //com.cyy.design.Person@6d6f6e28
        System.out.println(p3); //com.cyy.design.Person@6d6f6e28

        System.out.println(p1==p2); //true
        System.out.println(p1==p3); //true
    }
}
2、懒汉单例设计模式

懒汉单例设计模式就是调用getInstance()方法时才实例化对象,先不着急实例化对象,等到要用时才实例化,这就是懒汉式。

public class Person1 {
    //1、私有化构造方法
    private Person1(){}

    //2、声明唯一的类变量
    private static Person1 p;

    //3、定义方法,当用户调用时创建唯一的实例化对象,加上同步锁,防止多线程时实例化多个对象
    public static synchronized Person1 getInstance(){
        // 判断一下,如果p这个成语变量的值为null,就创建,不为null,说明该对象已经创建了,直接返回即可
        if(p == null){
            p = new Person1();
        }
        return p;
    }
}
class Test1{
    public static void main(String[] args) {
        Person1 p1 = Person1.getInstance();
        Person1 p2 = Person1.getInstance();
        Person1 p3 = Person1.getInstance();

        System.out.println(p1);//com.cyy.design.Person1@6d6f6e28
        System.out.println(p2);//com.cyy.design.Person1@6d6f6e28
        System.out.println(p3);//com.cyy.design.Person1@6d6f6e28

        System.out.println(p1==p2);//true
        System.out.println(p1==p3);//true
    }
}

2、多例设计模式

通过多例设计模式可以保证系统中应用该模式的类有固定数量的实例化对象。多例类要自我创建并管理自己的实例,还要向外界提供获取本类实例的方法。

实现步骤
  1. 创建一个类, 将构造方法私有化,使其不能在类的外部通过new关键字实例化该类对象。
  2. 在类中定义该类被创建的总数量
  3. 在类中定义存放类实例的list集合
  4. 在类中提供静态代码块,在静态代码块中创建类的实例
  5. 提供获取类实例的静态方法
public class Person2 {
    //1、私有化构造方法
    private Person2(){}

    //2、定义一个存放该类对象的集合
    private static ArrayList<Person2> list = new ArrayList<Person2>();
    
    //2.2、在静态代码块中创建固有数量的实例化对象,存放在集合里面
    static{
        for (int i = 0; i < 3; i++) {
            Person2 p = new Person2();
            list.add(p);
        }
    }

    //3、随机从集合里面获取一个实例化对象
    public static Person2 getInstance(){
        //随机获取一个集合下标
        Random random = new Random();
        int i = random.nextInt(list.size());

        return list.get(i);
    }
}

class Test2{
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            Person2 p = Person2.getInstance();
            System.out.println(p);
        }
        /*
            com.cyy.design.Person2@135fbaa4
            com.cyy.design.Person2@45ee12a7
            com.cyy.design.Person2@330bedb4
            com.cyy.design.Person2@45ee12a7
            com.cyy.design.Person2@330bedb4
            com.cyy.design.Person2@135fbaa4
            com.cyy.design.Person2@330bedb4
            com.cyy.design.Person2@330bedb4
            com.cyy.design.Person2@330bedb4
            com.cyy.design.Person2@45ee12a7
         */
    }
}

3、工厂模式

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。之前我们创建类对象时, 都是使用new 对象的形式创建, 除new对象方式以外, 工厂模式也可以创建对象。

//1.编写一个Car接口, 提供run方法
public interface Car {
    public void run();
}

//2.编写一个FaLaLi类实现Car接口,重写run方法
class FaLaLi implements Car{
    @Override
    public void run() {
        System.out.println("法拉利以每小时500公里行驶.........");
    }
}
//3.编写一个BenChi类实现Car接口
class BenChi implements Car{
    @Override
    public void run() {
        System.out.println("奔驰以每小时400公里行驶.........");
    }
}

//4.提供一个CarFactory(汽车工厂),用于生产汽车对象
class CarFactory{
    /**
     *
     * @param id 车的标识
     * @return
     */
    public Car createCar(String id){
        //若果想要生产奔池就返回一个BenChi对象,如果想要生产法拉利就返回FaLaLi对象,否者返回空
        if("BenChi".equals(id)){
            return new BenChi();
        }else if("FaLaLi".equals(id)){
            return new FaLaLi();
        }
        return null;
    }
}

class Test4{
    public static void main(String[] args) {
        CarFactory carFactory = new CarFactory();
        Car benChi = carFactory.createCar("BenChi");
        benChi.run();
        Car faLaLi = carFactory.createCar("FaLaLi");
        faLaLi.run();
    }
}

工厂模式的存在可以改变创建类的对象的方式,解决类与类之间的耦合

4、枚举【了解】

枚举是一种引用数据类型,java中的枚举是有固定个数对象的"特殊类"。如果有些类的对象是固定个数
的,就可以定义成枚举。比如性别,季节,方向。

public class Person3 {
    private String name;
    private Sex sex;

    public Person3() {
    }

    public Person3(String name, Sex sex) {
        this.name = name;
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "Person3{" +
                "name='" + name + '\'' +
                ", sex=" + sex +
                '}';
    }
}

enum Sex{
    BOY, GIRL;//男、女
}

class Test3{
    public static void main(String[] args) {
        Person3 p1 = new Person3("张三", Sex.BOY);
        Person3 p2 = new Person3("李四", Sex.GIRL);
        Person3 p2 = new Person3("李四", "男"); //这样就会报错
        System.out.println(p1.toString());
    }
}

枚举的本质是一个类,所以枚举中还可以有成员变量,成员方法等。
枚举的本质是一个类,我们刚才定义的Sex枚举最终效果如下:

enum Sex{
    BOY(3), GIRL(6);//男、女

    public int age;
    Sex(int age) {
        this.age = age;
    }

    public void show(){
        System.out.println(age);
    }
}

class Test3{
    public static void main(String[] args) {
        Person3 p1 = new Person3("张三", Sex.BOY);
        Person3 p2 = new Person3("李四", Sex.GIRL);

        Sex.BOY.show();
        Sex.GIRL.show();
        System.out.println(p1.toString());
    }
}

运行结果:
【单例模式、多例模式、工厂模式和枚举】

上一篇:python中动态生成类type的用法


下一篇:php面向对象高级应用一