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(); }
}
|
抽象工厂:可生成一系列“产品”,每系列”产品“可横向分为产品族
优点:可方便扩展产品族 缺点:单一产品的扩展,要改动香港系列的所有产品产品
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=?");
}
}
|
调停者
5 装饰器(Decorator)
6 责任链(ChainOfResponsibility)
责任链(ChainOfResponsibility):
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):源对象发出对应的事件,观察者触发对应的操作
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)
主要用来处理树状结构
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就是利用的享元模式,字符串会放入常量池
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)