Terminal 4.

设计模式

2024/09/11
loading

目前记录的模式:单例模式、工厂模式、策略模式、状态模式、观察者模式
持续更新中; ;

单例模式

确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例
只有一个实例—->构造方法只能是private,并且拥有一个当前类的静态成员变量

饿汉式实现

这个唯一的实例,在类加载的时候马上进行实例化

1
2
3
4
5
6
7
8
9
10
11
12
public class SingletonPattern{
public static void main(String[] args){
}
}
class Singleton{
private static Singleton singleton = new Singleton();
private Singleton(){}

public static Singleton getInstance(){
return singleton;
}
}

懒汉式实例

在类加载的时候不进行实例化,在第一次使用时(调用getinstance时)在进行实例化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class SingletonPattern{
public static void main(String[] args){
}
}
class Singleton{
private static Singleton singleton;
private Singleton(){}

public synchronized static Singleton getInstance(){
if(singleton == null)
singleton = new Singleton();
return singleton;
}//synchronized加锁,防止在多线程时多次实例化
}

双重检查锁
减小同步的范围 提高getinstance时的返回速度

1
2
3
4
5
6
7
8
public synchronized static Singleton getInstance(){
if(singleton == null)
synchronized(Singleton.class){
if(singleton == null)
singleton = new Singleton();
}
return singleton;
}

要加 volatile 修饰,
singleton = new Singleton() 可以拆解为3步:
1、分配内存,2、初始化对象,3、指向刚分配的地址
若发生重排序,假设 A 线程执行了1和3,还没有执行2,B线程来到判断 NULL,B线程就会直接返回还没初始化的instance了。volatile 可以避免重排序。
详见java多线程

在存在多个JVM虚拟机时会出现多个实例
一个JVM虚拟机使用多个类加载器,产生多个实例 ?

单例模式最佳以无状态的,比如工具类的形式提供

工厂模式

简单工厂模式

简单工厂模式又称为静态工厂方法模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都有共有的父类。

此处应有例图

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
public class SimpleFactory{
public static Product createProduct(String type){
if("A".equals(type))//最好常量在前,防止变量是null的情况报空指针
return new ProductA();
else
return new ProductB();
}
public static void main(String[] args){
Product product = SimpleFactory.createProduxt("A");
product.print();
}
}
abstract class Product{
public abstract void print();
}
class ProductA extends Product{

@Override
public void print(){
System.out.println("产品A");
}
}
class ProductB extends Product{

@Override
public void print(){
System.out.println("产品B");
}
}

实现对象的创建和使用分离

工厂模式

此处应有例图

新增一个产品,就新增一个工厂类,每一个具体的工厂都负责生产一种对应的具体产品
e.g. 抽象工厂(接口)Collection 具体工厂ArrayList和LinkedList,抽象产品Iterator,具体产品Itr和ListItr

抽象工厂模式

此处应有例图

使工厂不单可以生产某一大类产品,还可以生产其他大类产品,打破了一对一关系

策略模式

定义一组算法,将每个算法都封装起来,并且使他们之间可以互换。策略模式让算法独立于使用它的可乎而变化,也称为政策模式(Policy)。

1
2
3
4
5
6
7
8
import java.util.concurrent.ThreadPoolExecutor;
public class StrategyPattern{
public static void main(String[] args){
ThreadPoolExecutor executor = new ThreadPoolExecutor();

}
}


就是java城堡游戏里用的handler?

状态模式

状态模式(State Pattern):允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。其别名为状态对象(Objects for States),状态模式是一种对象行为型模式。

策略模式和状态模式都可以避免if-else语句的使用
优点:封装了转换规则,并枚举了可能的状态(策略),将所有与某个对状态(策略)有关的行为放到了状态例中,方便增加新的状态(策略)
缺点:增加系统类和对象的个数,如使用不当会导致程序结构或代码的混乱

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
public class StatePattern{
public static main(String[] args){
Content ZhangSan = new Content();
ZhangSan.changeStates(new Happy());
ZhangSan.doSomething();
ZhangSan.changeStates(new Angry());
ZhangSan.doSomething();
ZhangSan.changeStates(new Sad());
ZhangSan.doSomething();
}
}
abstract class State{
abstract void doWork();
}
class Happy extends State{
@Override
void doWork(){
System.out.println("积极主动!");
}
}
class Angry extends State{
@Override
void doWork(){
System.out.println("无精打采!");
}
}
class Sad extends State{
@Override
void doWork(){
System.out.println("啥也不干!");
}
}

class Content{
private State state;
public void changeState(State state){
this.state=state;
}
public void doSomething(){
state.doWork();
}
}

观察者模式

又称发布-订阅模式

观察者模式(Oberserver Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。

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
public class ObserverPattern{
public static void main(String[] args){
Debit ZhangSan = new ZhangSan();
ZhangSan.borrow(new WangWu());
ZhangSan.borrow(new ZhaoSi());
//state改变
ZhangSan.notifyCredits();
}
}
interface Debit{
void borrow(Credit credit);
void notifyCredits();
}
class ZhangSan implements Debit{
private List<Credit> allCredits = new ArrayList<>();
private Integer state =0;//1表示有钱
@Override
public void notifyCredits(){
allCredits.forEach(credit -> credit.takeMoney());
}

@Override
public void borrow(Credit credit){
allCredits.add(credit);
}
}
interface Credit(){
void takeMoney();
}
class WangWu implements Credit{
@Override
public void takeMoney(){
System.out.println("王五要钱!");
}
}

class ZhaoSi implements Credit{
@Override
public void takeMoney(){
System.out.println("赵四要钱!");
}
}

以上实例中,Debit为主题对象,Credit为观察者,主题对象负责去添加观察者(borrow)、通知观察者(notifyCredits)

CATALOG
  1. 1. 单例模式
    1. 1.1. 饿汉式实现
    2. 1.2. 懒汉式实例
  2. 2. 工厂模式
    1. 2.1. 简单工厂模式
    2. 2.2. 工厂模式
    3. 2.3. 抽象工厂模式
  3. 3. 策略模式
  4. 4. 状态模式
  5. 5. 观察者模式