单例模式和多例模式和工厂模式
1单例设计模式
学习目标
- 能够使用单例设计模式设计代码
内容讲解
- 正常情况下一个类可以创建多个对象
public static void main(String[] args) {
// 正常情况下一个类可以创建多个对象
Person p1 = new Person();
Person p2 = new Person();
Person p3 = new Person();
}
- 如果说有时一个对象就能搞定的事情 , 非要创建多个对象 , 浪费内存!!!
1.1 单例设计模式的作用
-
单例模式,是一种常用的软件设计模式。通过单例模式可以保证项目中,应用该模式的这个类只有一个实例。
即一个类只有一个对象实例。
-
好处 :可以节省内存,共享数据
1.2 单例设计模式实现步骤
- 将构造方法私有化,使其不能在类的外部通过new关键字实例化该类对象。
- 在该类内部产生一个唯一的实例化对象,并且将其封装为private static 类型的成员变量。
- 定义一个静态方法返回这个唯一对象。
1.3 单例设计模式的类型
根据创建对象的时机单例设计模式又分为以下两种:
-
饿汉单例设计模式
-
懒汉单例设计模式
=============================================================================================
1.4 饿汉单例设计模式
-
饿汉单例设计模式就是使用类的时候已经将对象创建完毕
不管以后会不会使用到该实例化对象,先创建了再说。很着急的样子,故被称为“饿汉模式”。
-
代码如下:
public class Singleton { // 1.将构造方法私有化,使其不能在类的外部通过new关键字实例化该类对象。 private Singleton() {} // 2.在该类内部产生一个唯一的实例化对象,并且将其封装为private static 类型的成员变量。 private static Singleton instance = new Singleton(); // 3.定义一个静态方法返回这个唯一对象。 public static Singleton getInstance() { return instance; } }
-
需求:定义一个皇帝类,要求对象只能存在一个。
=============================================================================================
1.5 懒汉单例设计模式
-
懒汉单例设计模式就是调用getInstance()方法时对象才被创建
也就是说先不急着实例化出对象,等要用的时候才实例化出对象。不着急,故称为“懒汉模式”。
代码如下:
public class Singleton {
// 2.在该类内部产生一个唯一的实例化对象,并且将其封装为private static类型的成员变量。
private static Singleton instance;// 0x001
// 1.将构造方法私有化,使其不能在类的外部通过new关键字实例化该类对象。
private Singleton() {}
// 3.定义一个静态方法返回这个唯一对象。要用的时候才例化出对象
public static synchronized Singleton getInstance() {
if(instance == null) {
instance = new Singleton();// 0x001
}
return instance;
}
}
- ##### 注意 :
- 懒汉单例设计模式在多线程环境下可能会实例化出多个对象,不能保证单例的状态,所以加上关键字:synchronized,保证其同步安全。
- 需求:使用懒汉单例 ,改写皇帝类的单例模式
```java
知识小结
-
单例模式可以保证系统中一个类只有一个对象实例。
-
实现单例模式的步骤:
- 将构造方法私有化,使其不能在类的外部通过new关键字实例化该类对象。
- 在该类内部产生一个唯一的实例化对象,并且将其封装为private static类型的成员变量。
- 定义一个静态方法返回这个唯一对象。
2 多例设计模式
学习目标
- 能使用多例设计模式设计代码
内容讲解
2.1 多例设计模式的作用
-
多例模式,是一种常用的设计模式之一。通过多例模式可以保证项目中,应用该模式的类有固定数量的实例。
多例类要自我创建并管理自己的实例,还要向外界提供获取本类实例的方法。
-
使用场景:线程池
线程池 = Executors.newFixedThreadPool(3);
2.2.实现步骤
1.创建一个类, 将构造方法私有化,使其不能在类的外部通过new关键字实例化该类对象。
2.在类中定义该类被创建对象的总数量
3.在类中定义存放类实例的list集合
4.在类中提供静态代码块,在静态代码块中创建类的实例
5.提供获取类实例的静态方法
2.3.实现代码
-
某一个学科有固定3位老师,年级中上该课程的老师就是这三位老师其中一位
要求使用多例模式 ,每次获取的都是这三位老师其中一位
import com.itheima.homework.Test;
import java.time.Period;
import java.util.ArrayList;
import java.util.Random;
/*
需求 : 某一个学科有固定3位老师,年级中上该课程的老师就是这三位老师其中一位
要求使用多例模式 ,每次获取的都是这三位老师其中一位
实现步骤 :
1.创建一个类, 将构造方法私有化,使其不能在类的外部通过new关键字实例化该类对象。
2.在类中定义该类被创建对象的总数量
3.在类中定义存放类实例的list集合
4.在类中提供静态代码块,在静态代码块中创建类的实例
5.提供获取类实例的静态方法
*/
public class Teacher {
// 1.创建一个类, 将构造方法私有化,使其不能在类的外部通过new关键字实例化该类对象。
private Teacher() {
}
// 2.在类中定义该类被创建对象的总数量
private static final int maxCount = 3;
// 3.在类中定义存放类实例的list集合
private static ArrayList<Teacher> list = new ArrayList<>();//{三个老师对象}
// 4.在类中提供静态代码块,在静态代码块中创建类的实例
static {
for (int i = 0; i < maxCount; i++) {
list.add(new Teacher());
}
}
// 5.提供获取类实例的静态方法
public static Teacher getInstance() {
Random r = new Random();
// 返回集合中的某一个老师
return list.get(r.nextInt(list.size()));
}
}
import org.junit.Test;
public class TeacherTest {
@Test
public void getInstance() {
for (int i = 0; i < 10; i++) {
Teacher teacher = Teacher.getInstance();
System.out.println(teacher);
}
}
}
2.4 小结
-
多例模式作用 : 可以保证项目中一个类有固定个数的实例, 在实现需求的基础上, 能够提高实例的复用性.
实现多例模式的步骤 :
- 创建一个类, 将构造方法私有化,使其不能在类的外部通过new关键字实例化该类对象。
- 在类中定义该类被创建的总数量
- 在类中定义存放类实例的list集合
- 在类中提供静态代码块,在静态代码块中创建类的实例
- 提供获取类实例的静态方法
3 工厂设计模式
学习目标
- 能够使用工厂设计模式设计代码
内容讲解
3.1 概述
- 工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。之前我们创建类对象时, 都是使用 new 对象的形式创建, 除new 对象方式以外, 工厂模式也可以创建对象.
3.2作用
- 解决类与类之间的耦合问题
3.3案例实践
-
需求:定义汽车工厂类,生产各种品牌的车
-
实现步骤
- 编写一个Car接口, 提供run方法
- 编写一个Falali类实现Car接口,重写run方法
- 编写一个Benchi类实现Car接口
- 提供一个CarFactory(汽车工厂),用于生产汽车对象
- 定义CarFactoryTest测试汽车工厂
实现代码
/*
- 需求:定义汽车工厂类,生产各种品牌的车
- 实现步骤
- 编写一个Car接口, 提供run方法
- 编写一个Falali类实现Car接口,重写run方法
- 编写一个Benchi类实现Car接口
- 提供一个CarFactory(汽车工厂),用于生产汽车对象
- 定义CarFactoryTest测试汽车工厂
*/
public class CarTest {
public static void main(String[] args) {
// 多态
// Car falali = CarFactory.getCar("Falali");
// Car falali = CarFactory.getCar("fghjkl");
// falali.run();
// 调用此方法getCar , 只能传入枚举项
CarFactory.getCar(CarBrand.FALALI);
}
}
// 汽车接口
interface Car {
public abstract void run();// 行驶
}
// 编写一个Falali类实现Car接口,重写run方法
class Falali implements Car {
@Override
public void run() {
System.out.println("法拉利3秒破百...");
}
}
// 编写一个Benchi类实现Car接口
class Benchi implements Car {
// public Benchi(int price) {
//
// }
@Override
public void run() {
System.out.println("法拉利5秒破百...");
}
}
// 枚举
enum CarBrand {
// 枚举项 : 每个枚举项都相当于枚举的对象
BENCHI, FALALI, DAZHONG, LASILAISI, AODI;
}
// 提供一个CarFactory(汽车工厂),用于生产汽车对象
class CarFactory {
public static Car getCar(CarBrand carBrand) {
switch (carBrand) {
case BENCHI:
return new Benchi();
case FALALI:
return new Falali();
//...
default:
return null;
}
}
}
提供一个CarFactory(汽车工厂),用于生产汽车对象
//class CarFactory {
// public static Car getCar(String carName) {
// if (carName.equals("Falali")) {
// return new Falali();
// } else if (carName.equals("Benchi")) {
// return new Benchi(1000000);
// }
// return null;// 传入的不是Falali或者Benchi 则返回null
// }
//}
知识小结
- 工厂模式的存在可以改变创建对象的方式,降低类与类之间的耦合问题.