某系统需要实现消息推送的需求。其中消息的类型包含普通、紧急、严重三种类型,消息的发送渠道又可以分为邮件、短信等方式。请设计出一套合理的消息推送的程序。
消息类型分为三种,消息的发送渠道又分为两种,两个不同维度可以分为2*3=6种类型。
消息类型普通邮件消息普通短信消息紧急邮件消息紧急短信消息严重邮件消息严重短信消息顶层消息接口
public interface Message { /** * 发送消息 * @param content 消息内容 * @param toUser 消息发送对象 **/ void send(String content, String toUser); }6种消息类型
普通邮件消息
public class CommonMailMessage implements Message { @Override public void send(String content, String toUser) { System.out.println("发送普通邮件消息给" + toUser + ",消息内容:" + content); } }普通短信消息
public class CommonSmsMessage implements Message { @Override public void send(String content, String toUser) { System.out.println("发送普通短信消息给" + toUser + ",消息内容:" + content); } }紧急邮件消息
public class UrgentMailMessage implements Message { @Override public void send(String content, String toUser) { System.out.println("发送紧急邮件消息给" + toUser + ",消息内容:" + content); } }紧急短信消息
public class UrgentSmsMessage implements Message { @Override public void send(String content, String toUser) { System.out.println("发送紧急短信消息给" + toUser + ",消息内容:" + content); } }严重邮件消息
public class SeriousMailMessage implements Message { @Override public void send(String content, String toUser) { System.out.println("发送严重邮件消息给" + toUser + ",消息内容:" + content); } }严重短信消息
public class SeriousSmsMessage implements Message { @Override public void send(String content, String toUser) { System.out.println("发送严重短信消息给" + toUser + ",消息内容:" + content); } }客户端测试
public static void main(String[] args) { Message message = new UrgentMailMessage(); message.send("1号服务器宕机了!", "贤子磊"); Message message2 = new CommonSmsMessage(); message2.send("明天一起吃饭哈。", "贤子磊"); }输出
发送紧急邮件消息给贤子磊,消息内容:1号服务器宕机了! 发送普通短信消息给贤子磊,消息内容:明天一起吃饭哈。这样设计看似是蛮不错的设计方案,但是存在极大地问题
如果后续消息的发送途径新增了其他形式,消息的类型也扩展了其余形式,则类的数量成倍地增长,导致系统过于臃肿,难以维护。如果消息的发送方式各式各样,很难使用统一的动作来定义消息的发送,扩展性极差。既然消息的定义维度存在多种,那么我们可以通过组合的方式来实现。这就引出了桥接模式。
我们将消息分为发送渠道和等级类型两种组合,两种组合互不干扰,通过组合的方式进行桥接。这里由于只有两个维度,为了简单起见,我们将等级类型整合到消息的主干上,发送渠道作为组件组合到主干上。
定义发送渠道抽象接口及实现
渠道接口
public interface Channel { String getDescription(); }接口实现
邮件渠道
public class MailChannel implements Channel{ @Override public String getDescription() { return "邮件"; } }短信渠道
public class SmsChannel implements Channel{ @Override public String getDescription() { return "短信"; } }定义消息主干抽象类及等级类型的实现
消息主干抽象类
public abstract class AbstractMessage { /** * 消息的发送渠道 */ protected Channel channel; /** * 消息的类型 */ protected String level; /** * 发送消息 * @param content 消息内容 * @param toUser 消息发送对象 * @author xianzilei **/ public abstract void send(String content, String toUser); }等级类型的实现
普通消息
public class CommonMessage extends AbstractMessage { public CommonMessage(Channel channel) { super.channel = channel; super.level = "普通"; } @Override public void send(String content, String toUser) { System.out.println("发送" + level + channel.getDescription() + "消息给" + toUser + ",消息内容:" + content); } }紧急消息
public class UrgentMessage extends AbstractMessage { public UrgentMessage(Channel channel) { super.channel = channel; super.level = "紧急"; } @Override public void send(String content, String toUser) { System.out.println("发送" + level + channel.getDescription() + "消息给" + toUser + ",消息内容:" + content); } }严重消息
public class SeriousMessage extends AbstractMessage { public SeriousMessage(Channel channel) { super.channel = channel; super.level = "严重"; } @Override public void send(String content, String toUser) { System.out.println("发送" + level + channel.getDescription() + "消息给" + toUser + ",消息内容:" + content); } }客户端测试
public static void main(String[] args) { Channel channel = new SmsChannel(); AbstractMessage message = new SeriousMessage(channel); message.send("数据库服务器宕机了!", "贤子磊"); }输出
发送严重短信消息给贤子磊,消息内容:数据库服务器宕机了!桥接模式(Bridge Pattern):将抽象与实现分离,使它们可以独立变化。
桥接模式一般包含如下角色
Abstraction:抽象化角色
一般为抽象类,并包含一个对实现化对象的引用
abstract class Abstraction { //实现化对象的引用 protected Implementor imple; protected Abstraction(Implementor imple) { this.imple=imple; } public abstract void Operation(); }Refined Abstraction:扩展抽象化角色
是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法
class RefinedAbstraction extends Abstraction { protected RefinedAbstraction(Implementor imple) { super(imple); } public void Operation() { System.out.println("扩展抽象化(Refined Abstraction)角色被访问" ); imple.OperationImpl(); } }Implementor:实现化角色
定义实现化角色的接口,供扩展抽象化角色调用
interface Implementor { public void OperationImpl(); }Concrete Implementor:具体实现化角色
给出实现化角色接口的具体实现
class ConcreteImplementorA implements Implementor { public void OperationImpl() { System.out.println("具体实现化(Concrete Implementor)角色被访问" ); } }