简介
设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。
本节主要介绍中介模式、代理模式、责任模式。
知识点
- 中介模式
- 代理模式
- 责任链模式
中介模式
简介
定义了一个对象,该对象封装了一组对象的交互方式。对象之间的通信将封装在中介对象中。对象不再直接相互通信,而是通过中介进行通信。这减少了通信对象之间的依赖性,从而减少了耦合。
优点
- 避免一组交互对象之间的紧密耦合。
- 可以独立地改变一组对象之间的交互。
类图
对应中介对象来说,互相交互的对象叫做同事类,中介者对象维护同事类之间的关系,中介对象需要知道所有同事对象,所以也会带来一个问题,当同事类过多时,中介者类将异常复杂。
- Mediator:抽象中介类,用于与各同事对象之间进行通信
- ConcreteMediator:具体中介类,协调各同事类。
- Colleague:抽象同事类。
- ConcreteColleague:具体同事类。
具体实现:
第一步:定义Mediator
第二步:定义抽象Colleague
第三步:定义具体Colleagueclass
第四步:定义具体中介者ConcreteMediator,具体中介者通过协调各同事对象实现协作行为,了解并维护它的各个同事。
第五步:定义Client,测试中介者模式的使用
编程实战
比如我们要实现一个聊天室的功能,聊天室就是中介,而聊天的人就是一个同事类,发送的每个消息都由聊天室转发给其他人。
AbstractChatRoom.java(Mediator):
public abstract class AbstractChatRoom {
public abstract void notice(String message, User user);
}
ChatRoom.java(ConcreteMediator):
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);
}
}
}
}
User.java(Colleague)。
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);
}
UserA.java(ConcreteColleague):
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);
}
}
UserB.java(ConcreteColleague):
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);
}
}
Client.java:
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("再见!");
}
}
编译运行:
javac Client.java
java Clent
用户A发送 你好!
用户B收到 你好!
用户B发送 再见!
用户A收到 再见!
代理模式
简介
代理模式:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
优点
- 隐藏原始对象并控制对象的访问。
- 访问对象时提供其他的功能。
类图
说明:
- Subject: 一个客户端可用的公开的功能接口。
- RealSubject:实现 Subject 接口的类,提供了接口方法的具体实现。
- Proxy:实现 Subject 接口的代理类,通过 RealSubject 类的业务逻辑方法来实现抽象方法,可以附加自己的操作。
编程实战
假设我们需要建设一栋楼房,但是建设之前我们需要购买原材料(如水泥…),接着才可以开始建设,楼房主体建设完成后,还需要封顶操作。
LouSubject.java:
public interface LouSubject{
void build();
}
LouRealSubject.java:
public class LouRealSubject implements LouSubject{
@Override
public void build(){
System.out.println("建设实验楼");
}
}
LouProxy.java:
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("封顶");
}
}
LouClient.java
public class LouClient{
public static void main(String[] args){
LouSubject proxy = new LouProxy();
proxy.build();
}
}
编译运行:
javac LouClient.java
java LouClient
购买材料
建设实验楼
封顶
责任链模式
责任链模式是一种由命令对象源和一系列处理对象组成的设计模式。每个处理对象都包含定义它可以处理的命令对象类型的逻辑;其余的传递给链中的下一个处理对象。还存在一种机制,用于将新处理对象添加到该链的末尾。责任链模式在结构上与装饰器模式几乎相同,不同之处在于对于装饰器,所有类都处理请求,而对于责任链,链中的一个类恰好处理请求。
优点
- 避免将请求的发送方与其接收方耦合。
- 可以使用多个接收器处理请求。
handler:抽象处理者。
ConcreteHandler:具体处理者,接受到请求后,可以选择处理请求或者传递给下一个处理者。
编程实战
假设我们有一个请假系统,不同的职位可以处理不同的请假请求,比如:
组长:可以处理两天以内的请求
厂长:可以处理七天以内的请求
老板:可以处理十五天以内的请求
如果组长可以处理,那么就直接处理了,如果组长不可以处理,那么我们再继续往下传递。
Handler.java:
public abstract class Handler {
/**
* 下个处理者
*/
protected Handler successor;
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public abstract void handlerRequest(int heaven);
}
GroupLeaderHandler.java
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);
}
}
}
}
FactoryManagerHandler.java:
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);
}
}
}
}
BossHandler.java:
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);
}
}
}
}
Client.java:
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);
}
}
编译运行:
javac Client.java
java Client
组长处理
厂长处理
老板处理
总结
本节主要内容是对常用的设计模式进行讲解,主要包含以下知识点:
- 中介模式
- 代理模式
- 责任链模式