【设计模式】桥接模式(Bridge)

面向对象:

  • 松耦合
  • 高内聚

面向对象系统追求的目标就是尽可能地提高系统模块内部的内聚(Cohesion)、尽可能降低模块间的耦合(Coupling) 。然而这也是面向对象设计过程中最难把握的部分。
GOF在提出Bridge模式的时候指出:Bridge模式的用意是“将 抽象化(Abstraction)实现化(Implementation) 脱耦,使得二者可以独立地变化”。

耦合和脱耦

  • 耦合就是两个实体的行为的某种强关联。
  • 将它们的强关联去掉,就是耦合的解脱,或称脱耦。

脱耦是指将抽象化和实现化之间的耦合解脱开,或者说是将它们之间的强关联改换成弱关联。

  • 将两个角色之间的继承关系改为聚合关系,就是将它们之间的强关联改换成为弱关联
  • 桥连模式中的所谓脱耦,就是指在一个软件系统的抽象化和实现化之间使用组合/聚合关系而不是继承关系,从而使两者可以相对独立地变化。这就是桥连模式的用意。

模式结构

在这里插入图片描述

  • 由抽象化角色和修正抽象化角色组成的抽象化等级结构。
  • 由实现化角色和两个具体实现化角色所组成的实现化等级结构。
  • 在桥接模式中的桥接是单向的,也就是只能是抽象部分的对象去使用具体实现部分的对象,而不能反过来。也就是个单向桥。
  • 使用Bridge模式和原始解决方案的根本区别在于是通过继承还是通过合成\聚合的方式去实现一个功能需求。因此面向对象分析和设计中有一个原则就是:
    Favor Composition Over lnheritance
    (类似继承但不是继承)

模式代码

using System;

namespace 桥接模式
{
    abstract class Implementor
    {
        public abstract void Operation();
    }

    class ConcreteImplementorA:Implementor
    {
        public override void Operation()
        {
            Console.WriteLine("具体实现A的方法执行");
        }
    }

    class ConcreteImplementorB:Implementor
    {
        public override void Operation()
        {
            Console.WriteLine("具体实现B的方法执行");
        }
    }

    class Abstraction
    {
        protected Implementor implementor;

        public void SetImplementor(Implementor implementor)
        {
            this.implementor = implementor;
        }

        public virtual void Operation()
        {
            implementor.Operation();
        }
    }

    class RefinedAbstraction:Abstraction
    {
        public override void Operation()
        {
            implementor.Operation();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Abstraction ab = new RefinedAbstraction();

            ab.SetImplementor(new ConcreteImplementorA());
            ab.Operation();

            ab.SetImplementor(new ConcreteImplementorB());
            ab.Operation();

            Console.Read();
        }
    }
}

本质

分离抽象和实现

举例

ps:仅代表个人思路

【问题】
考虑这样一个实际的业务功能:发送提示消息。

  • 基本上所有带业务流程处理的系统都会有这样的功能,比如某人有新的工作了,需要发送一条消息提示他。
  • 从业务_上看,消息又分成普通消息加急消息特急消息多种,不同的消息类型,业务功能处理是不-样的,比如加急消息是在消息上添加加急,而特急消息除了添加特急外,还会做一条催促的记录,多久不完成会继续催促。从发送消息的手段上看,又有系统内短消息手机短消息邮件等等。

现在要实现这样的发送提示消息的功能,该如何实现呢?
【代码】

public class MyAuthenticator extends Authenticator {
	private String userName=null;  
    private String password=null;  
       
    public MyAuthenticator(){}
    
    public MyAuthenticator(String username, String password) {   
        this.userName = username;   
        this.password = password;   
    }   
    protected PasswordAuthentication getPasswordAuthentication(){  
        return new PasswordAuthentication(userName, password);  
    }  
}
public abstract class AbstractMessage {
	protected MessageImplementor impl;

	public AbstractMessage(MessageImplementor impl) {
		super();
		this.impl = impl;
	}
	
	public void sendMessage(String message,String toUser) {
		this.impl.send(message, toUser);
	}
}
public class CommonMessage extends AbstractMessage {

	public CommonMessage(MessageImplementor impl) {
		super(impl);
	}
	
	public void sendMessage(String message,String toUser) {
		super.sendMessage(message, toUser);
	}

}
public class UrgencyMessage extends AbstractMessage {

	public UrgencyMessage(MessageImplementor impl) {
		super(impl);
	}

	public void sendMessage(String message,String toUser) {
		message="加急:"+message;
		super.sendMessage(message, toUser);
	}
	
	public Object watch(String messageld) {
		return null;
	}
}

public class SpecialUrgencyMessage extends AbstractMessage {

	public SpecialUrgencyMessage(MessageImplementor impl) {
		super(impl);
	}

	public void sendMessage(String message,String toUser) {
		message="特急:"+message;
		super.sendMessage(message, toUser);
	}
	
	public void hurry(String messageld) {
	}
}
public interface MessageImplementor {
	public void send(String message,String toUser);
}
public class MessageSMS implements MessageImplementor {

	@Override
	public void send(String message, String toUser) {
		System.out.println("使用站内短消息的方式,发送消息:"+message+"给"+toUser);
	}

}
public class MessageMobile implements MessageImplementor {

	@Override
	public void send(String message, String toUser) {
		System.out.println("使用手机短消息的方式,发送消息:"+message+"给"+toUser);
	}

}

public class MessageEmail implements MessageImplementor {

	@Override
	public void send(String message, String toUser) {
		Properties props = new Properties();
		props.put("mail.smtp.host", "smtp.163.com"); //smtp服务器地址 
		props.put("mail.smtp.auth", true);  //是否需要认证 
		MyAuthenticator myauth = new MyAuthenticator("lavinia_dv1005@163.com","********"); 
		
		Session session = Session.getInstance(props,myauth); 
		session.setDebug(true); //打开debug功能
		
		Message msg = new MimeMessage(session);
		try {
			msg.setFrom(new InternetAddress("lavinia_dv1005@163.com"));//设置发件人
			msg.setText(message); //设置邮件内容
			msg.setSubject(message); //设置邮件主题
			msg.setRecipient(Message.RecipientType.TO, new InternetAddress(toUser)); 
			Transport.send(msg);
		} catch(AddressException e) {
			System.out.println("地址错误!");
			e.printStackTrace();
		} catch(MessagingException e) {
			System.out.println("信息错误!");
			e.printStackTrace();
		}
	}

}

public class Client {

	public static void main(String[] args) {
		MessageImplementor impl =new MessageSMS();
		AbstractMessage m=new CommonMessage(impl);
		m.sendMessage("请喝一杯茶", "dv17866703607@163.com");
		m=new UrgencyMessage(impl);
		m.sendMessage("请喝一杯茶", "dv17866703607@163.com");
		m=new SpecialUrgencyMessage(impl);
		m.sendMessage("请喝一杯茶", "dv17866703607@163.com");
		impl=new MessageMobile();
		m=new CommonMessage(impl);
		m.sendMessage("请喝一杯茶", "dv17866703607@163.com");
		m=new UrgencyMessage(impl);
		m.sendMessage("请喝一杯茶", "dv17866703607@163.com");
		m=new SpecialUrgencyMessage(impl);
		m.sendMessage("请喝一杯茶", "dv17866703607@163.com");
		impl=new MessageEmail();
		m=new CommonMessage(impl);
		m.sendMessage("请喝一杯茶", "dv17866703607@163.com");
		m=new UrgencyMessage(impl);
		m.sendMessage("请喝一杯茶", "dv17866703607@163.com");
		m=new SpecialUrgencyMessage(impl);
		m.sendMessage("请喝一杯茶", "dv17866703607@163.com");
	}

}

【UML图】
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值