常用设计模式
常用设计模式
桥接模式(双向拓展模式):Bridge
分离抽象和具体,通过聚合联系在一起
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/* 这个是礼物类,礼物是抽象的,里面定义一个具体礼物实现类 */
public abstract class Gift {
GiftImpl impl; // 具体礼物
public Gift(GiftImpl impl){
this.impl = impl;
}
}
/* 具体礼物实现类父类 */
public class GiftImpl {
}
/* 书作为具体礼物,继承GiftImpl */
public class Book extends GiftImpl {
}
/* 花作为具体礼物,继承GiftImpl */
public class Flower extends GiftImpl {
}
/* 大的礼物,作为“大”这个抽象的概念继承Gift */
public class BigGift extends Gift {
public BigGift(GiftImpl impl){
super(impl);
}
}
/* 小的礼物,作为“小这个抽象的概念继承Gift” */
public class SmallGift extends Gift {
public SmallGift(GiftImpl impl) {
super(impl);
}
}
/* main方法 */
public class BridgeMain {
public static void main(String[] args) {
// 通过聚合,把抽象的和具体的联系起来
// 通过抽象和具体的组合,有更多的不同礼物
Gift gift1 = new BigGift(new Book()); // 大的书作为礼物
Gift gift2 = new BigGift(new Book()); // 小的书作为礼物
}
}
组合模式:Composite
一般需要树状结构时使用
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82/* 所有种类节点的父类 */
public abstract class Node {
public abstract void printNode();
}
/* 分支节点(目录,节点下面还有内容) */
import java.util.ArrayList;
import java.util.List;
public class BranchNode extends Node {
private String name;
private List<Node> nodes = new ArrayList<>();
public BranchNode(String name) {
this.name = name;
}
public void printNode() {
System.out.println(this.name);
}
public BranchNode addNode(Node n){
this.nodes.add(n);
return this;
}
public void printAllNode(){
this.printAllNode(this, 0);
}
public void printAllNode(Node node, int depth){
for (int i = 0; i < depth; i++) System.out.print("-|");
node.printNode();
if(node instanceof BranchNode){
for(Node n : ((BranchNode)node).nodes){
printAllNode(n, depth+1);
}
}
}
}
/* 叶子节点(文件,下面没内容) */
public class LeafNode extends Node {
private String context;
public LeafNode(String context) {
this.context = context;
}
public void printNode() {
System.out.println(this.context);
}
}
/* main方法 */
public class CompositeMain {
public static void main(String[] args) {
BranchNode root = new BranchNode("root");
BranchNode a1 = new BranchNode("a1");
BranchNode a2 = new BranchNode("a2");
LeafNode b1 = new LeafNode("b1");
LeafNode b2 = new LeafNode("b2");
LeafNode b3 = new LeafNode("b3");
root.addNode(a1).addNode(a2).addNode(b1);
a2.addNode(b2).addNode(b3);
root.printAllNode();
}
}
/*
结果:
root
-|a1
-|a2
-|-|b2
-|-|b3
-|b1
*/
责任链模式:Chain of Responsibility 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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118/* 所有filter或者filterchain都需要实现该接口 */
public interface Filter {
void doFilter(Request request, Response response, FilterChain chain);
}
/* FilterChain */
import java.util.ArrayList;
import java.util.List;
public class FilterChain implements Filter {
private List<Filter> filters = new ArrayList<>();
private int index = 0;
public FilterChain addFilter(Filter f){
filters.add(f);
return this;
}
public void doFilter(Request request, Response response, FilterChain chain) {
if(index == filters.size()) return;
Filter filter = filters.get(index++);
filter.doFilter(request, response, chain);
}
}
/* HTMLFilter */
public class HTMLFilter implements Filter {
public void doFilter(Request request, Response response, FilterChain chain) {
String str = " -> HTMLFilter";
request.setStr(request.getStr() + str);
chain.doFilter(request, response, chain);
response.setStr(response.getStr() + str);
}
}
/* SensitiveFilter */
public class SensitiveFilter implements Filter {
public void doFilter(Request request, Response response, FilterChain chain) {
String str = " -> SensitiveFilter";
request.setStr(request.getStr() + str);
chain.doFilter(request, response, chain);
response.setStr(response.getStr() + str);
}
}
/* Request */
public class Request {
private String str;
public Request() {
}
public Request(String str) {
this.str = str;
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public String toString() {
return this.str;
}
}
/* Response */
public class Response {
private String str;
public Response() {
}
public Response(String str) {
this.str = str;
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public String toString() {
return this.str;
}
}
/* main方法 */
public class CorMain {
public static void main(String[] args) {
FilterChain chain = new FilterChain();
chain.addFilter(new HTMLFilter()).addFilter(new SensitiveFilter());
Request request = new Request("request");
Response response = new Response("response");
chain.doFilter(request, response, chain);
System.out.println(request);
System.out.println(response);
}
}
/*
结果:
request -> HTMLFilter -> SensitiveFilter
response -> SensitiveFilter -> HTMLFilter
*/
装饰器模式:Decorator 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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82/* 装饰器和被装饰的类都要实现这个接口 */
public interface Decor {
void draw();
}
/* Circle */
public class Circle implements Decor {
public void draw() {
System.out.println("Circle::draw()");
}
}
/* Rectangle */
public class Rectangle implements Decor {
public void draw() {
System.out.println("Rectangle::draw()");
}
}
/* Decorator 装饰器的抽象父类 */
public abstract class DecorDecorator implements Decor {
protected Decor decoratedDecor;
public DecorDecorator(Decor decoratedDecor){
this.decoratedDecor = decoratedDecor;
}
public void draw(){
decoratedDecor.draw();
}
}
/* RedDecorDecorator 红色装饰器,为图行添加颜色 */
public class RedDecorDecorator extends DecorDecorator {
public RedDecorDecorator(Decor decoratedDecor) {
super(decoratedDecor);
}
public void draw() {
decoratedDecor.draw();
setRedBorder(decoratedDecor);
}
private void setRedBorder(Decor decoratedDecor){
System.out.println("Border Color: Red");
}
}
/* main方法 */
public class DecoratorMain {
public static void main(String[] args) {
Shape circle = new Circle();
Shape redCircle = new RedShapeDecorator(new Circle());
Shape redRectangle = new RedShapeDecorator(new Rectangle());
System.out.println("Circle with normal border");
circle.draw();
System.out.println("\nCircle of red border");
redCircle.draw();
System.out.println("\nRectangle of red border");
redRectangle.draw();
}
}
/*
结果:
Circle with normal border
Circle::draw()
Circle of red border
Circle::draw()
Border Color: Red
Rectangle of red border
Rectangle::draw()
Border Color: Red
*/
外观模式: Facade
隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口,解决内部复杂问题,对外提供简单接口。其实就是把一些有联系的复杂功能通过一个接口提供。
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71/* 各种提供功能的类实现这个接口 */
public interface Shape {
void draw();
}
/* Circle */
public class Circle implements Decor {
public void draw() {
System.out.println("Circle::draw()");
}
}
/* Rectangle */
public class Rectangle implements Decor {
public void draw() {
System.out.println("Rectangle::draw()");
}
}
/* Square */
public class Square implements Shape {
public void draw() {
System.out.println("Square::draw()");
}
}
/* ShapeMaker,提供复杂功能的API类 */
public class ShapeMaker {
private Shape circle;
private Shape rectangle;
private Shape square;
public ShapeMaker() {
circle = new Circle();
rectangle = new Rectangle();
square = new Square();
}
public void drawCircle(){
circle.draw();
}
public void drawRectangle(){
rectangle.draw();
}
public void drawSquare(){
square.draw();
}
}
/* main方法 */
public class FacadeMain {
public static void main(String[] args) {
// 通过ShapeMaker提供各种图形的功能
ShapeMaker shapeMaker = new ShapeMaker();
shapeMaker.drawCircle();
shapeMaker.drawRectangle();
shapeMaker.drawSquare();
}
}
/*
结果:
Circle::draw()
Rectangle::draw()
Square::draw()
*/
工厂模式:Factory
工厂模式,主要有简单工厂、工厂方法、抽象工厂三种
- 简单工厂:就是一个工厂创建不同的同类型对象返回
- 工厂方法:每个类都有自己的工厂来创建对象,便于单个产品的拓展
- 抽象工厂:通过继承抽象工厂,实现不同族的工厂,用于返回对应的不同族对象;便于拓展不同的产品族
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89// 抽象工厂:
/* AbstractFactory */
public abstract class AbstractFactory {
abstract Food createFood();
abstract Vehicle createVehicle();
}
/* AbstractFactoryExtOne */
public class AbstractFactoryExtOne extends AbstractFactory {
Food createFood() {
return new Bread();
}
Vehicle createVehicle() {
return new Car();
}
}
/* AbstractFactoryExtTwo */
public class AbstractFactoryExtTwo extends AbstractFactory {
Food createFood() {
return new Beef();
}
Vehicle createVehicle() {
return new Plane();
}
}
/* Food */
public abstract class Food {
abstract void printName();
}
/* Vehicle */
public abstract class Vehicle {
abstract void go();
}
public class Beef extends Food {
void printName() {
System.out.println("牛肉");
}
}
public class Bread extends Food {
void printName() {
System.out.println("面包");
}
}
public class Car extends Vehicle {
public void go(){
System.out.println("车启动...");
}
}
public class Plane extends Vehicle {
public void go() {
System.out.println("飞机启动...");
}
}
/* main方法 */
public class AbstractFactoryMain {
public static void main(String[] args) {
AbstractFactory fc = new AbstractFactoryExtOne();
// AbstractFactory fc = new AbstractFactoryExtTwo();
Vehicle v = fc.createVehicle();
Food f = fc.createFood();
v.go();
f.printName();
}
}
享元模式:FlyWeight
通过共享元对象(比较小的或者常用的对象),减少创建过多对象,类似于池的技术
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100public class Word {
private char w;
public Word(char w) {
this.w = w;
}
public char getW() {
return w;
}
}
public class AWord extends Word {
public AWord() {
super('A');
}
}
public class BWord extends Word {
public BWord() {
super('B');
}
}
public class CWord extends Word {
public CWord() {
super('C');
}
}
/* WordPool */
import java.util.ArrayList;
import java.util.List;
public class WordPool {
private int size;
private List<Word> words = new ArrayList<>();
public WordPool(){
addWord(new AWord());
addWord(new BWord());
addWord(new CWord());
}
public WordPool addWord(Word w){
this.words.add(w);
size++;
return this;
}
public WordPool extendWordList(List<Word> wList){
for (Word word : wList) {
this.words.add(word);
size++;
}
return this;
}
public Word getWord(int index){
if(index >= size || index < 0) index = size-1;
return this.words.get(index);
}
public int getSize() {
return size;
}
public List<Word> getWords() {
return words;
}
}
/* main方法 */
public class FlyWeightMain {
public static void main(String[] args) {
WordPool wordPool = new WordPool();
Word w1 = wordPool.getWord(0);
Word w2 = wordPool.getWord(1);
Word w3 = wordPool.getWord(2);
System.out.println(w1.getW());
System.out.println(w2.getW());
System.out.println(w3.getW());
System.out.println("===========");
Word w4 = wordPool.getWord(0);
System.out.println(w4 == w1);
}
}
/*
结果:
A
B
C
===========
true
*/
迭代器模式:Iterator
主要用于集合元素的遍历
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
public class IteratorMain {
public static void main(String[] args) {
_Collection<String> list = new _ArrayList<>();
for (int i = 0; i < 16; i++) {
list.add("str" + i);
}
// 通过迭代器模式,实现通用的集合遍历:
_Iterator iterator = list.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
new ArrayList<>();
}
}
/* 自定义的集合接口:_Collection */
public interface _Collection<E> {
void add(E o);
int size();
_Iterator iterator(); // 规定集合中要有获取迭代器实现的方法
}
/* 自定义的迭代器接口:_Iterator */
public interface _Iterator<E> {
boolean hasNext(); // 判断是否还有下一个元素
E next(); // 返回下一个元素
}
/* 自定义的List集合:_ArrayList,实现_Collection */
public class _ArrayList<E> implements _Collection<E>{
private Object[] objects;
private int capacity;
private int index = 0;
public _ArrayList() {
this.objects = new Object[10];
this.capacity = 10;
}
public _ArrayList(int capacity) {
this.objects = new Object[capacity];
this.capacity = capacity;
}
public void add(E o) {
if(index >= capacity){
Object[] temp = new Object[this.capacity=(capacity * 2)];
System.arraycopy(this.objects, 0, temp, 0, index);
this.objects = temp;
}
this.objects[index++] = o;
}
public int size() {
return this.index;
}
public _Iterator iterator() {
return new Itr();
}
// 使用内部类实现迭代器接口
private class Itr<E> implements _Iterator<E>{
int len = -1;
public boolean hasNext() {
if(index <= ++len){
return false;
}
return true;
}
public E next() {
return (E)objects[len];
}
}
}
/* main方法 */
public class IteratorMain {
public static void main(String[] args) {
_Collection<String> list = new _ArrayList<>();
for (int i = 0; i < 6; i++) {
list.add("str" + i);
}
// 通过迭代器模式,实现通用的集合遍历:
_Iterator iterator = list.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
new ArrayList<>();
}
}
/*
结果:
str0
str1
str2
str3
str4
str5
*/中介者模式:Mediator
用来降低多个对象和类之间的通信复杂性。
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/* 用户类 */
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User(String name){
this.name = name;
}
public void sendMessage(String message){
ChatRoom.showMessage(this, message);
}
}
/* 聊天室类 */
public class ChatRoom {
public static void showMessage(User user, String message){
System.out.println(new Date().toString()
+ " [" + user.getName() +"] : " + message);
}
}
/* main方法 */
public class MediatorMain {
public static void main(String[] args) {
User robert = new User("Robert");
User john = new User("John");
robert.sendMessage("Hi! John!");
john.sendMessage("Hello! Robert!");
}
}
/*
结果:
Sun Jul 19 19:03:25 CST 2020 [Robert] : Hi! John!
Sun Jul 19 19:03:25 CST 2020 [John] : Hello! Robert!
*/
观察者模式:Observer Pattern
当对象间存在一对多关系时,则使用观察者模式(Observer 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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126public interface DoThingObserver {
void actionOnDoThing(DoThingEvent event);
}
public abstract class DoThingEvent<T> {
abstract T getSource();
}
public class OneThingObserver implements DoThingObserver {
public void actionOnDoThing(DoThingEvent event) {
System.out.println("do one thing.");
}
}
public class TwoThingObserver implements DoThingObserver {
public void actionOnDoThing(DoThingEvent event) {
System.out.println("do two thing.");
}
}
public class OneThingEvent extends DoThingEvent<Student> {
private long timestamp;
private String loc;
private Student source;
public OneThingEvent(long timestamp, String loc, Student source) {
this.timestamp = timestamp;
this.loc = loc;
this.source = source;
}
Student getSource() {
return this.source;
}
}
public class TwoThingEvent extends DoThingEvent<Teacher> {
private String loc;
private long timestamp;
private Teacher source;
public TwoThingEvent(String loc, long timestamp, Teacher source) {
this.loc = loc;
this.timestamp = timestamp;
this.source = source;
}
Teacher getSource() {
return this.source;
}
}
import java.util.ArrayList;
import java.util.List;
public class Student {
private String name;
private int age;
private List<DoThingObserver> observers = new ArrayList<>();
public Student addObserver(DoThingObserver observer){
observers.add(observer);
return this;
}
public void action(){
System.out.println("student action");
OneThingEvent event = new OneThingEvent(System.currentTimeMillis(), "one thing", this);
for (DoThingObserver o : observers) {
o.actionOnDoThing(event);
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
/* main方法 */
public class ObserverMain {
public static void main(String[] args) {
Student std = new Student();
std.action(); // 还没添加事件,所以输出为空
System.out.println("=============");
std.addObserver(new OneThingObserver());
std.action(); // 添加事件后,会执行事件对应的方法
// 因为事件监听(观察者)是一个函数式接口,所以可以通过lambda表达式添加监听
std.addObserver(event ->
System.out.println("use lambda to do thing.")
);
System.out.println("=============");
std.action(); // 此时有2个事件
}
}
/*
结果:
student action
=============
student action
do one thing.
=============
student action
do one thing.
use lambda to do thing.
*/
原型模式:Prototype
Java中有原型模式的实现:Object的clone()方法。使用需要:
1、实现Cloneable接口(标记性接口,没有需要实现的方法)
2、重写clone()方法
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
35public class Apple implements Cloneable {
private String color;
public Apple(String color) {
this.color = color;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
public String toString() {
return "Apple{" +
"color='" + color + '\'' +
'}';
}
}
/* main方法 */
public class PrototypeMain {
public static void main(String[] args) throws CloneNotSupportedException {
Apple apple = new Apple("red");
Apple cloneApple = (Apple) apple.clone(); // 浅克隆,引用的实际内容没有克隆
System.out.println(apple);
System.out.println(cloneApple);
}
}
/*
结果:
Apple{color='red'}
Apple{color='red'}
*/
代理模式:Proxy
代理模式中,有静态代理和动态代理。其中静态代理通过聚合实现,类似于装饰器模式。
动态代理在Java中可以使用JDK的proxy创建动态代理,需要被代理对象实现接口;使用cglib创建动态代理对象,不需要被代理对象实现接口。动态代理实际是使用asm来操作字节码修改或者创建代理。
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123public interface Movable {
void move();
}
public class Car implements Movable {
public void move() {
System.out.println("the car moving...");
}
}
public class Plane {
public void move(){
System.out.println("plane fly ...");
}
}
// 静态代理:
public class CarProxy implements Movable {
private Movable m;
public CarProxy(Movable m) {
this.m = m;
}
public void move() {
System.out.println("静态代理:car proxy...");
m.move();
}
}
// 动态代理:
public class CarDynamicProxy implements InvocationHandler {
// 动态代理的代理实现功能,要实现InvocationHandler接口的invoke()方法
Movable m;
public CarDynamicProxy(Movable m) {
this.m = m;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("动态代理:car move ...");
Object o = method.invoke(m, args);
return o;
}
}
/**
* 飞机动态代理:使用cglib创建动态代理对象,不需要被代理对象实现接口
* 需要引入cglib的jar包:
<dependencies>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.1</version>
</dependency>
</dependencies>
*/
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class PlaneCGLibProxy implements MethodInterceptor {
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("cglib动态代理:plane fly ...");
Object result = methodProxy.invokeSuper(o, objects);
return result;
}
}
/* main方法 */
import net.sf.cglib.proxy.Enhancer;
import java.lang.reflect.Proxy;
public class ProxyMain {
public static void main(String[] args) {
// 静态代理
Movable m1 = new CarProxy(new Car());
Movable m2 = new CarLogProxy(new Car());
m1.move();
m2.move();
System.out.println("================");
// 动态代理
System.getProperties().put("jdk.proxy.ProxyGenerator.saveGeneratedFiles", "true"); // 设置输出动态代理创建的动态代理字节码文件
Movable m = (Movable) Proxy.newProxyInstance(Car.class.getClassLoader(),
new Class[]{Movable.class},
new CarDynamicProxy(new Car()));
m.move();
// 使用cglib动态代理
System.out.println("================");
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Plane.class);
enhancer.setCallback(new PlaneCGLibProxy());
Plane plane = (Plane)enhancer.create();
plane.move();
}
}
/*
结果:
静态代理:car proxy...
the car moving...
静态代理:car move log...
the car moving...
================
动态代理:car move ...
the car moving...
================
cglib动态代理:plane fly ...
plane fly ...
*/
单例模式: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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110// 1、饿汉式单例:随着类的加载创建一个单例出来
public class Singleton1 {
private static final Singleton1 INSTANCE = new Singleton1();
private Singleton1(){} // 私有构造函数,防止外部创建实例
public static Singleton1 getInstance(){
return INSTANCE;
}
}
// 2、饿汉式单例:随着类的加载创建一个单例出来,这里使用静态代码块创建单例
public class Singleton2 {
private static final Singleton2 INSTANCE;
static {
INSTANCE = new Singleton2();
}
private Singleton2(){} // 私有构造函数,防止外部创建实例
public static Singleton2 getInstance(){
return INSTANCE;
}
}
// 3、懒汉式单例,实例延迟加载,但是会造成线程安全问题
public class Singleton3 {
private static Singleton3 INSTANCE;
private Singleton3(){}
public static Singleton3 getInstance(){
if(null == INSTANCE){
INSTANCE = new Singleton3();
}
return INSTANCE;
}
}
// 4、懒汉式单例,实例延迟加载,使用synchronized加锁,同步方法,线程安全
public class Singleton4 {
private static Singleton4 INSTANCE;
private Singleton4(){}
public static synchronized Singleton4 getInstance(){
if(null == INSTANCE){
INSTANCE = new Singleton4();
}
return INSTANCE;
}
}
// 5、懒汉式单例,实例延迟加载,使用synchronized加锁(双重锁),同步方法,线程安全
public class Singleton5 {
private static volatile Singleton5 INSTANCE;
private Singleton5(){}
public static Singleton5 getInstance(){
if(null == INSTANCE){
synchronized (Singleton5.class){
if(null == INSTANCE) INSTANCE = new Singleton5();
}
}
return INSTANCE;
}
}
// 6、懒汉式单例,实例延迟加载,JVM加载 外部类 时不会加载 内部类,所以可以使用 静态内部类 来实现 懒汉式单例。
public class Singleton6 {
private Singleton6(){}
private static class Singleton{
private static final Singleton6 INSTANCE = new Singleton6();
}
public static Singleton6 getInstance(){
return Singleton.INSTANCE;
}
}
// 7、懒汉式枚举单例,实例延迟加载,线程安全,还可以防止反序列化。
public enum Singleton7 {
INSTANCE;
/**
* 这是枚举单例的测试方法,枚举单例只需定义一个枚举值即可
*/
public void printHashCode(){
System.out.println(INSTANCE.hashCode());
}
}
// 8、解决单例模式的其他问题:1.反射强制实例化问题;2.反序列化问题
public class Singleton8 implements Serializable {
private static final Singleton8 INSTANCE = new Singleton8();
private Singleton8() {
if(INSTANCE != null){
throw new RuntimeException("不能强制实例化"); // 解决反射强制实例化问题
}
} // 私有构造函数,防止外部创建实例
public static Singleton8 getInstance(){
return INSTANCE;
}
public Object readResolve(){
return INSTANCE; // 解决反序列化问题
}
}
状态模式:State
根据不同的状态,对同一动作会有不同的反应
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
58/* 状态抽象类父类 */
public abstract class PersonState {
abstract void smile();
abstract void cry();
abstract void say();
}
public class HappyState extends PersonState {
void smile() {
System.out.println("happy smile");
}
void cry() {
System.out.println("happy cry");
}
void say() {
System.out.println("happy say");
}
}
public class Person {
private PersonState state;
public Person(PersonState state) {
this.state = state;
}
public void smile(){
state.smile();
}
public void cry(){
state.cry();
}
public void say(){
state.say();
}
}
/* main方法 */
public class StateMain {
public static void main(String[] args) {
Person p = new Person(new HappyState());
p.smile();
p.cry();
p.say();
}
}
/*
结果:
[Student{name='tianqi', age=20, weight=60, height=180}, Student{name='zhaoliu', age=19, weight=61, height=175}, Student{name='lisi', age=18, weight=62, height=178}]
*/
模板模式(模板方法):Template
在抽象的父类(模板)中,
定义了一个执行一系列方法的方法,
其中执行的一系列方法可以是抽象的也可以是实现的,
子类在继承父类后通过重写或者实现父类的方法,
实现模板执行钩子函数也可以是模板方法,
在模板中预留钩子,通过重写执行钩子方法,
模板方法也可以是回调函数,通过预留回调方法,通过重写执行回调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
53public abstract class MyTemplate {
public void doTemplate(){
op1();
op2();
op3();
op4();
}
void op1() {
}
void op2() {
}
void op3() {
}
void op4() {
}
}
public class DoTemplate extends MyTemplate {
public void op1(){
System.out.println("op1");
}
void op2() {
System.out.println("op2");
}
void op4() {
System.out.println("op4");
}
}
public class TemplateMain {
public static void main(String[] args) {
MyTemplate tple = new DoTemplate();
tple.doTemplate();
}
}
/*
结果:
op1
op2
op4
*/
访问者模式:Visitor
在结构不变的情况下动态改变对于内部元素的动作
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160public interface Visitor {
void visitCpu(CPU cpu);
void visitMemory(Memory memory);
void visitBord(Bord bord);
}
public abstract class ComputerPart {
public abstract void accept(Visitor v);
public abstract double getPrice();
}
public class CPU extends ComputerPart{
private double price;
public CPU() {
this.price = 1000.0;
}
public CPU(double price) {
this.price = price;
}
public void accept(Visitor v) {
v.visitCpu(this);
}
public double getPrice() {
return this.price;
}
public void setPrice(double price) {
this.price = price;
}
}
public class Memory extends ComputerPart {
private double price;
public Memory() {
this.price = 400.0;
}
public Memory(double price) {
this.price = price;
}
public void accept(Visitor v) {
v.visitMemory(this);
}
public double getPrice() {
return this.price;
}
public void setPrice(double price) {
this.price = price;
}
}
public class Bord extends ComputerPart {
private double price;
public Bord() {
this.price = 600.0;
}
public Bord(double price) {
this.price = price;
}
public void accept(Visitor v) {
v.visitBord(this);
}
public double getPrice() {
return this.price;
}
public void setPrice(double price) {
this.price = price;
}
}
public class PersonVisitor implements Visitor {
private double totalPrice = 0.0;
public void visitCpu(CPU cpu) {
this.totalPrice = totalPrice + (cpu.getPrice() * 0.9);
}
public void visitMemory(Memory memory) {
this.totalPrice = totalPrice + (memory.getPrice() * 0.85);
}
public void visitBord(Bord bord) {
this.totalPrice = totalPrice + (bord.getPrice() * 0.95);
}
public double getTotalPrice() {
return totalPrice;
}
}
public class Computer {
private CPU cpu;
private Memory memory;
private Bord bord;
public Computer() {
this.cpu = new CPU();
this.memory = new Memory();
this.bord = new Bord();
}
public Computer(double cpuPrice, double memoryPrice, double bordPrice) {
this.cpu = new CPU(cpuPrice);
this.memory = new Memory(memoryPrice);
this.bord = new Bord(bordPrice);
}
public void accept(Visitor v){
this.cpu.accept(v);
this.memory.accept(v);
this.bord.accept(v);
}
}
public class VisitorMain {
public static void main(String[] args) {
Computer computer = new Computer(1068.88, 868.99, 488.99);
PersonVisitor personVisitor = new PersonVisitor();
computer.accept(personVisitor);
System.out.println(personVisitor.getTotalPrice());
}
}
/*
结果:
电脑价格:2165.174
*/
常用的设计模式大概就是这些了~
谢谢浏览!END~
Original author: John Doe & wooyee.Landucheg
Original link: http://yoursite.com/2020/07/26/常用设计模式/
Copyright Notice: Please indicate the source of the reprint (must retain the author's signature and link)