Java 常见设计模式

设计模式(Design pattern) 代表了最佳实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

设计模式简要说明

本次示例 主要介绍一下模式

  • 中介模式
  • 代理模式
  • 责任链模式

中介模式

简介

定义一个对象,该对象封装了一组对象的交互方式。对象之间的通信将封装在中介对象中。对象不再直接相互通信而是通过中介进行通信。这减少了通信对象之间的依赖性,从而减少了耦合。

优点
  1. 避免一组交互对象之间的紧密耦合
  2. 可以独立地改变一组对象之间的交互
类图

中介模式

示例代码

比如 我们要实现一个聊天室 聊天室就是中介,聊天的人就是一个同事类,发送的消息都由聊天室转发给别人

首先我们新建一个聊天室文件

1
2
3
public abstract class AbstractChatRoom {
public abstract void notice(String message, User user);
}

然后我们新建一个聊天室

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.util.ArrayList;
import java.util.List;


public class ChatRoom extends AbstractChatRoom {
private List<User> users = new ArrayList<>();

public void register(User user) {
users.add(user);
}
@Override
public void notice(String message, User user) {
for (User u : users) {
if (u != user) {
u.getMessage(message);
}
}
}
}

现在我们新建一个用户基类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public abstract class User {
protected AbstractChatRoom chatRoom;

public User(AbstractChatRoom chatRoom) {
this.chatRoom = chatRoom;
}

/**
* 发送消息
*
* @param msg
*/
public abstract void sendMessage(String msg);

/**
* 接受消息
*
* @param msg
*/
public abstract void getMessage(String msg);
}

模拟用户A

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class UserA extends User {
public UserA(AbstractChatRoom chatRoom) {
super(chatRoom);
}

@Override
public void sendMessage(String msg) {
System.out.println("用户A发送 " + msg);
chatRoom.notice(msg, this);
}

@Override
public void getMessage(String msg) {
System.out.println("用户A收到 " + msg);
}
}

模拟用户B

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class UserB extends User {
public UserB(AbstractChatRoom chatRoom) {
super(chatRoom);
}

@Override
public void sendMessage(String msg) {
System.out.println("用户B发送 " + msg);
chatRoom.notice(msg, this);
}

@Override
public void getMessage(String msg) {
System.out.println("用户B收到 " + msg);
}
}

客户端

1
2
3
4
5
6
7
8
9
10
11
public class Client {
public static void main(String[] args) {
ChatRoom chatRoom = new ChatRoom();
UserA userA = new UserA(chatRoom);
UserB userB = new UserB(chatRoom);
chatRoom.register(userA);
chatRoom.register(userB);
userA.sendMessage("你好!");
userB.sendMessage("再见!");
}
}

自己编译运行 查看效果

代理模式

简介

代理模式:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不合适或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用

优点
  1. 隐藏原始对象并控制对象的访问
  2. 访问对象时提供其他的功能
类图

代理模式

说明:

  • Subject : 一个客户端可用的公开的功能接口
  • RealSubject: 实现Subject接口的类,提供了接口方法的具体实现
  • Proxy: 实现Subject接口的代理类,通过RealSubject类的业务逻辑方法来实现抽象方法,可以附加自己的操作
示例

假设我们需要建设一栋楼房,但是建设之前我们需要购买原材料(如水泥……)接着才能开始建设,楼房主体建设完成后,还需要封顶

首先建立一个 构建接口

1
2
3
public interface LouSubject{
void build();
}

建设大楼主程序

1
2
3
4
5
6
public class LouRealSubject implements LouSubject{
@Override
public void build(){
System.out.println("建设实验楼");
}
}

建设大楼需要购买材料方法

1
2
3
4
5
6
7
8
9
10
11
12
public class LouProxy implements LouSubject{
private LouSubject target;
public LouProxy(){
this.target = new LouRealSubject();
}
@Override
public void build(){
System.out.println("购买材料");
target.build();
System.out.println("封顶");
}
}

使用主客户端执行程序

1
2
3
4
5
6
public class LouClient{
public static void main(String[] args){
LouSubject proxy = new LouProxy();
proxy.build();
}
}

责任链模式

责任链模式是一种由命令对象源和一系列处理对象组成的设计模式。每个处理对象都包含它可以处理的命令对象类型的逻辑;其余的传递给链中的下一个处理对象。还存在一种机制,用于将新处理对象添加到该链的末尾。责任链模式还在结构上与装饰器模式几乎相同不同之处在于对于装饰器。所有类都处理请求,而对于责任链,链中的一个类恰好处理请求。

优点
  1. 避免将请求的发送方与其接收方耦合
  2. 可以使用多个接收器处理请求
类图

责任链模式

handler : 抽象处理者
ConcreteHandler:具体处理者,接受到请求后,可以选择处理请求或者传递给下一个处理者

示例代码

假设我们有一个 OA 系统 不同的职位可以处理不同的审批流

组长: 可以处理两天以内的审批
厂长: 可以处理七天以内的审批
老板: 可以处理十五天以内的审批
如果组长可以处理,那么久直接处理了,如果组长不可以处理,那么我们再继续往下传递

处理程序

1
2
3
4
5
6
7
8
9
10
11
12
public abstract class Handler {
/**
* 下个处理者
*/
protected Handler successor;

public void setSuccessor(Handler successor) {
this.successor = successor;
}

public abstract void handlerRequest(int heaven);
}

组长处理程序

1
2
3
4
5
6
7
8
9
10
11
12
public class GroupLeaderHandler extends Handler {
@Override
public void handlerRequest(int heaven) {
if (heaven <= 2) {
System.out.println("组长处理");
}else {
if (super.successor != null) {
super.successor.handlerRequest(heaven);
}
}
}
}

厂长处理程序

1
2
3
4
5
6
7
8
9
10
11
12
public class FactoryManagerHandler extends Handler{
@Override
public void handlerRequest(int heaven) {
if (heaven <= 7) {
System.out.println("厂长处理");
}else {
if (super.successor != null) {
super.successor.handlerRequest(heaven);
}
}
}
}

老板处理

1
2
3
4
5
6
7
8
9
10
11
12
public class BossHandler extends Handler {
@Override
public void handlerRequest(int heaven) {
if (heaven <= 15) {
System.out.println("老板处理");
}else {
if (super.successor != null) {
super.successor.handlerRequest(heaven);
}
}
}
}

模拟发起请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Client {
public static void main(String[] args) {
Handler groupLeaderHandler = new GroupLeaderHandler();
Handler factoryManagerHandler = new FactoryManagerHandler();
Handler bossHandler = new BossHandler();
groupLeaderHandler.setSuccessor(factoryManagerHandler);
factoryManagerHandler.setSuccessor(bossHandler);
//请假一天
groupLeaderHandler.handlerRequest(1);
//请假6天
groupLeaderHandler.handlerRequest(6);
//请假10天
groupLeaderHandler.handlerRequest(10);
}
}