设计模式
创建型模式
单例模式
-
单例模式:确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
-
要求:
- 确保一个类只有一个实例:构造方法只能是
private
的;并且拥有一个当前类的静态成员变量; - 向整个系统提供这个实例:提供一个静态成员方法;
- 确保一个类只有一个实例:构造方法只能是
-
实现方式:
-
饿汉式:类加载的时候就进行实例化;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16/**
* @author ming
* @date 2023.09.20
* @about 单例模式(饿汉式)
*/
public class Singleton1 {
private static Singleton1 singleton = new Singleton1();
private Singleton1(){
}
public static Singleton1 getInstance(){
return singleton;
}
} -
懒汉式:在类被第一次使用的时候进行实例化;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19/**
* @author ming
* @date 2023.09.20
* @about 单例模式(懒汉式)
*/
public class Singleton2 {
private static Singleton2 singleton ;
private Singleton2(){
}
// 加锁,确保在多线程下,只被实例化一次
public synchronized static Singleton2 getInstance(){
if(singleton==null){
singleton = new Singleton2();
}
return singleton;
}
}以上代码可以优化,在类第一次被使用之后进行实例化,之后就不需要加锁,因此另外一种方式是 双重检查锁;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30/**
* @author ming
* @date 2023.09.20
* @about 单例模式(懒汉式)- 多重检查锁
*/
public class Singleton3 {
private volatile static Singleton3 singleton ;
private Singleton3(){
}
public static Singleton3 getInstance(){
if(singleton==null){
// 加锁,确保在多线程下,只被实例化一次
synchronized (Singleton3.class){
if(singleton==null){
singleton = new Singleton3();
/*
* 这一步包括
* 1. 分配内存
* 2. 初始化对象
* 3. 地址指向分配的内存
* 为防止发生重排序,用volatile修饰singleton静态变量
*/
}
}
}
return singleton;
}
}
-
-
应用场景:单例模式的最佳实践就是无状态的,例如工具类(网站计数器,应用程序的日志等);
简单工厂模式
-
简单工厂模式:又称为静态工厂方法模式,属于类的创建模式。在简单工厂模式中,可以根据具参数的不同返回不同的实例;简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实力通常具有相同的父类。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38/**
* @author ming
* @date 2023.09.25
* @about 简单工厂模式
*/
public class SimpleFactory {
public static Product createProduct(String type) {
if (type.equals("A")) {
return new ProductA();
} else {
return new ProductB();
}
}
public static void main(String[] args) {
Product a = createProduct("A");
a.print();
}
}
abstract class Product {
public abstract void print();
}
class ProductA extends Product {
public void print() {
System.out.println("ProductA");
}
}
class ProductB extends Product {
public void print() {
System.out.println("ProductB");
}
} -
缺点:不够灵活,如果新增一个类,那么就要修改工厂类。
工厂模式
-
工厂模式:定义一个用于创建类的对象,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57/**
* @author ming
* @date 2023.09.25
* @about 工厂模式
*/
// 动物接口
interface Animal {
void speak();
}
// 工厂接口
interface AnimalFactory {
Animal createAnimal();
}
// 狗类
class Dog implements Animal {
public void speak() {
System.out.println("汪汪汪!");
}
}
// 猫类
class Cat implements Animal {
public void speak() {
System.out.println("喵喵喵!");
}
}
// 狗工厂类
class DogFactory implements AnimalFactory {
public Animal createAnimal() {
return new Dog();
}
}
// 猫工厂类
class CatFactory implements AnimalFactory {
public Animal createAnimal() {
return new Cat();
}
}
public class Factory {
public static void animalAct(AnimalFactory fact) {
Animal a = fact.createAnimal();
a.speak();
}
public static void main(String[] args) {
animalAct(new DogFactory());
animalAct(new CatFactory());
}
} -
局限性:工厂模式要求需要被创建的类都属于同一个大类;
抽象工厂模式
-
抽象工厂模式:抽象工厂模式提供了一种创建一系列相关或相互依赖对象的接口,而无需指定具体实现类。通过使用抽象工厂模式,可以将客户端与具体产品的创建过程解耦,使得客户端可以通过工厂接口来创建一族产品。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37/**
* @author ming
* @date 2023.09.25
* @about 抽象工厂模式
*/
// 工厂接口
interface AbstractFactory {
Animal createAnimal();
Food createFood();
}
interface Animal {
}
interface Food {
}
class Dog implements Animal {
}
class noodles implements Food {
}
// 具体工厂实现
class SuperFacory implements AbstractFactory {
public Animal createAnimal() {
return new Dog();
}
public Food createFood() {
return new noodles();
}
}
结构型模式
装饰器模式
-
装饰器模式:动态的给一个对象添加一些新的功能。就增加功能来说,装饰器模式比生成子类更加灵活。
-
装饰器模式是在不改变核心功能的基础上去新增一些新的功能,和代理模式非常地相似;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41/**
* @author ming
* @date 2023.09.26
* @about 装饰器模式
*/
public class DecoratorPattern {
}
// 抽象接口,代表那些需要被装饰的对象
interface Robot {
public void doSomething();
}
// 第一代机器人
class Robot1 implements Robot {
public void doSomething() {
System.out.println("对话");
System.out.println("唱歌");
}
}
// 装饰器
class RobotDecorator implements Robot {
private Robot robot;
RobotDecorator(Robot robot) {
this.robot = robot;
}
public void doSomething() {
robot.doSomething();
}
// 扩展
public void doMoreThing() {
robot.doSomething(); // 原有功能
System.out.println("跳舞"); // 新的功能
}
} -
装饰器模式和静态代理的区别
- 装饰器模式就是为了增强目标类;静态代理设计模式是为了保护和隐藏目标对象。
- 装饰器模式和代理模式都是对原有对象的功能进行增强,但是装饰器模式可以进行多次扩展。
适配器模式
-
适配器模式:将一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38/**
* @author ming
* @date 2023.09.26
* @about 适配器模式
*/
public class AdapterPattern {
public static void main(String[] args) {
new Adapter(new Speaker()).translate();
}
}
class Speaker {
public String speaker() {
return "你好!";
}
}
// 适配器接口
interface Translator {
public String translate();
}
// 适配器
class Adapter implements Translator {
private Speaker speaker;
Adapter(Speaker speaker) {
this.speaker = speaker;
}
public String translate() {
String result = speaker.speaker();
// 翻译,转达等业务
return result;
}
}
观察者模式
- 观察者模式:定义了对象间的一种一对多的依赖关系,使得每当一个对象状态发生改变时,其相关依赖关系皆得到通知并被自动更新。观察者模式也被称为 “发布-订阅模式”。
评论