文章

Java设计模式

Java设计模式

Java设计模式

1 单例模式(Singleton)

1.1. 饿汉式

类加载到内存后,就实例化一个单例,JVM保证线程安全 简单实用,推荐使用!

唯一缺点:不管用到与否,类装载时就完成实例化

Class.forName(“”) (话说你不用的,你装载它干啥)

1
2
3
4
5
private static final Mgr01 INSTANCE = new Mgr01();
private Mgr01() {};
public static Mgr01 getInstance() {
    return INSTANCE;
}

1.2. 懒汉式

虽然达到了按需初始化的目的,但却带来线程不安全的问题

1
2
3
4
5
6
7
private static Mgr03 INSTANCE;
private Mgr03() {}
public static Mgr03 getInstance() {
    if (INSTANCE == null) 
        INSTANCE = new Mgr03();
    return INSTANCE;
}
synchronized

修饰方法,但是效率会下降

1
2
3
4
5
6
7
private static Mgr04 INSTANCE;
private Mgr04() {}
public static synchronized Mgr04 getInstance() {
    if (INSTANCE == null) 
        INSTANCE = new Mgr04();
    return INSTANCE;
}
双重检查
1
2
3
4
5
6
7
8
9
10
11
private static volatile Mgr06 INSTANCE; 
private Mgr06() {}
public static Mgr06 getInstance() {
    if (INSTANCE == null) {
        synchronized (Mgr06.class) {
            if(INSTANCE == null) 
                INSTANCE = new Mgr06();
        }
    }
    return INSTANCE;
}

1.3. 其他形式

静态内部类

1
2
3
4
5
6
7
private Mgr07() {}
private static class Mgr07Holder {
    private final static Mgr07 INSTANCE = new Mgr07();
}
public static Mgr07 getInstance() {
    return Mgr07Holder.INSTANCE;
}

直接使用枚举

不仅可以解决线程同步,还可以防止反序列化。

1
2
3
public enum Mgr08 {
    INSTANCE;
}

2 策略模式(Strategy)

适用于通用的比较方法

1
2
3
4
package java.lang;
public interface Comparable<T> {
	public int compareTo(T o);
}

比较器:和通用 compareTo 不同的比较策略

1
2
3
4
5
6
package java.util;
@FunctionalInterface
public interface Comparator<T> {
	int compare(T o1, T o2);
    //others...
}
1
2
3
4
5
6
7
8
9
10
public class Achievement implements Comparable<Achievement> {
    private int chinese;
    private int math;
    private int english;
    private int totalScore;
     @Override
    public int compareTo(Achievement achievement) {
        return this.totalScore - achievement.totalScore;
    }
}

数学成绩比较器

1
2
3
4
5
6
public class MathComparator implements Comparator<Achievement> {
    @Override
    public int compare(Achievement a1, Achievement a2) {
        return a1.getMath() - a2.getMath();
    }
}

3 工厂模式(Factory)

简单工厂模式:简单工厂类生成不同的对象

SimpleXXXactory.createXXX()

1
2
3
4
5
public class SimpleTestPaperFactory {
    public static ChineseTestPaper createChinesePaper() {        return new ChineseTestPaper();    }
    public static MathTestPaper createMathPaper() {        return new MathTestPaper();    }
    public static EnglishTestPaper createEnglishPaper() {        return new EnglishTestPaper();    }
}

工厂模式:具体类的具有独有的生成工厂

优点:方便产品单一的扩展,只需要增加对应的产品工厂

XXXFactory.create()

1
public class MathTestPaper implements Testable {}
1
public interface Testable {}
1
2
3
public class MathTestPaperFactory {
    public static Testable create() {        return new MathTestPaper();    }
}

抽象工厂:可生成一系列“产品”,每系列”产品“可横向分为产品族

优点:可方便扩展产品族 缺点:单一产品的扩展,要改动香港系列的所有产品产品

img

1
2
3
4
public abstract class AbstractTestPaperFactory {
    abstract ChineseTestPaper createChineseTestPaper();
    abstract MathTestPaper createMathTestPaper();
}
1
2
3
public abstract class ChineseTestPaper  {
    abstract void articleTitle();
}
1
2
3
public abstract class MathTestPaper {
    abstract void additionalQuestions();
}
1
2
3
4
5
6
7
8
9
10
11
public class Grade1TestPaperFactory extends AbstractTestPaperFactory {
    @Override
    public ChineseTestPaper createChineseTestPaper() {
        return new Grade1ChineseTestPaper();
    }

    @Override
    public MathTestPaper createMathTestPaper() {
        return new Grade1MathTestPaper();
    }
}
1
2
3
4
5
6
7
8
9
10
public class Grade2TestPaperFactory extends AbstractTestPaperFactory {
    @Override
    public ChineseTestPaper createChineseTestPaper() {
        return new Grade2ChineseTestPaper();
    }
    @Override
    public MathTestPaper createMathTestPaper() {
        return new Grade2MathTestPaper();
    }
}
1
2
3
4
5
6
public class Grade1ChineseTestPaper extends ChineseTestPaper {
    @Override
    void articleTitle() {
        System.out.println("Grade1ChineseTestPaperFactory ArticleTitle is eee");
    }
}
1
2
3
4
5
6
public class Grade1MathTestPaper extends MathTestPaper{
    @Override
    void additionalQuestions() {
        System.out.println("Grade1MathTestPaper additionalQuestions is 1+1=?");
    }
}
1
2
3
4
5
6
public class Grade2ChineseTestPaper extends ChineseTestPaper {
    @Override
    void articleTitle() {
        System.out.println("Grade2ChineseTestPaperFactory ArticleTitle is sanzijing");
    }
}
1
2
3
4
5
6
public class Grade2MathTestPaper extends MathTestPaper{
    @Override
    void additionalQuestions() {
        System.out.println("Grade2MathTestPaper additionalQuestions is 2*X+5=0 X=?");
    }
}

4 门面(Facade)调停者(Mediator)

image-20240115143311800

调停者

image-20240115143939835

5 装饰器(Decorator)

image-20240115153638840

image-20240131155921544

6 责任链(ChainOfResponsibility)

责任链(ChainOfResponsibility):

image-20240115221553694

image-20240115220834387

image-20240115223351591

1
2
3
interface Filter {
    boolean doFilter(Request request, Response response, FilterChain chain);
}
1
2
3
4
5
6
class Request {
    String msg;
}
class Response {
    String msg;
}
1
2
3
4
5
6
7
8
9
class Request1Filter implements Filter {
    @Override
    public boolean doFilter(Request request, Response response, FilterChain chain) {
        request.msg = request.msg.replaceAll("1", "ONE");
        chain.doFilter(request, response);
        response.msg = response.msg.replaceAll("9", "NINE");
        return false;
    }
}
1
2
3
4
5
6
7
8
9
class Request2Filter implements Filter {
    @Override
    public boolean doFilter(Request request, Response response, FilterChain chain) {
        request.msg = request.msg.replaceAll("2", "TWO");
        chain.doFilter(request, response);
        response.msg = response.msg.replaceAll("8", "EIGHT");
        return false;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class FilterChain {
    List<Filter> filters = new ArrayList<>();
    int index = 0;
    FilterChain add(Filter f) {
        filters.add(f);
        return this;
    }
    void doFilter(Request request, Response response) {
        if (index == filters.size()) return;
        Filter filter = filters.get(index);
        index++;
        filter.doFilter(request, response, this);
    }
}

7 观察者(Observer)

观察者(Observer):源对象发出对应的事件,观察者触发对应的操作

image-20240115235333024

image-20240116003118706

1
2
3
abstract class Event<T> {
    abstract T getSource();
}
1
2
3
interface Observer {
    void actionOnPlagiarism(PlagiarismEvent event);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class PlagiarismEvent extends Event<Student> {
    long time;
    String teacher;
    Student source;

    public PlagiarismEvent(long time, String teacher, Student source) {
        this.time = time;
        this.teacher = teacher;
        this.source = source;
    }

    @Override
    Student getSource() {
        return source;
    }
}

当学生作弊时:observers 对应的所有老师会执行 actionOnPlagiarism

每个老师的 actionOnPlagiarism 内进行自身的规则匹配或执行不同的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Student {
    String name;
    public Student(String name) {        this.name = name;    }
    List<Observer> observers = new ArrayList<>();
    {
        observers.add(new TeacherZhang());
        observers.add(new TeacherZhao());
        observers.add(new TeacherWang());
    }
    public void Plagiarism() {
        for (Observer observer : observers) {
            observer.actionOnPlagiarism(new PlagiarismEvent(System.currentTimeMillis(), "ALL", this));
        }
    }
}
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
class TeacherZhang implements Observer {
    public void reminder() {
        System.out.println("张:禁止小动作");
    }
    @Override
    public void actionOnPlagiarism(PlagiarismEvent event) {
        System.out.println("张发现" + event.getSource().name + "作弊");
        reminder();
    }
}

class TeacherZhao implements Observer {
    public void confiscation() {
        System.out.println("赵:没收作弊工具");
    }

    @Override
    public void actionOnPlagiarism(PlagiarismEvent event) {
        System.out.println("赵发现" + event.getSource().name + "作弊");

        confiscation();
    }
}

class TeacherWang implements Observer {
    public void eiction() {
        System.out.println("王:逐出考场");
    }

    @Override
    public void actionOnPlagiarism(PlagiarismEvent event) {
        System.out.println("王发现" + event.getSource().name + "作弊");
        if (event.teacher.equals("ALL"))
            return;
        eiction();
    }
}

8 组合模式(Composite)

主要用来处理树状结构

image-20240130163233259

1
2
3
abstract class Node {
    abstract public void p();
}
1
2
3
4
5
6
7
8
class LeafNode extends Node {
    String content;
    public LeafNode(String content) {this.content = content;}
    @Override
    public void p() {
        System.out.println(content);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
class BranchNode extends Node {
    List<Node> nodes = new ArrayList<>();
    String name;
    public BranchNode(String name) {this.name = name;}
    @Override
    public void p() {
        System.out.println(name);
    }
    public void add(Node n) {
        nodes.add(n);
    }
}

9 享元模式(Flyweight)

java中String就是利用的享元模式,字符串会放入常量池

image-20240130164616616

1
2
3
4
class Bullet{
    public UUID id = UUID.randomUUID();
    boolean living = true;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class BulletPool {
    List<Bullet> bullets = new ArrayList<>();
    {
        for(int i=0; i<5; i++) bullets.add(new Bullet());
    }
    /**
     * 当b不是活着的时候,将其return出去
     */
    public Bullet getBullet() {
        for(int i=0; i<bullets.size(); i++) {
            Bullet b = bullets.get(i);
            if(!b.living) return b;
        }
        return new Bullet();
    }
}
1
2
3
4
5
6
7
String s1 = "abc";
String s2 = "abc";
String s3 = new String("abc");
String s4 = new String("abc");
System.out.println(s1 == s2); //true
System.out.println(s1 == s3); //false
System.out.println(s3.intern() == s1);//true

10 静态代理与动态代理(Proxy)

image-20240131160015927

本文由作者按照 CC BY 4.0 进行授权