桥接模式详解
目录
桥接模式简介
定义
桥接模式(Bridge Pattern)是一种结构型设计模式,它将抽象部分与实现部分分离,使它们可以独立地变化。桥接模式通过组合的方式建立两个类之间的联系,而不是继承。
核心思想
- 分离抽象和实现:将抽象部分与实现部分分离
- 组合优于继承:使用组合关系而不是继承关系
- 独立变化:抽象和实现可以独立地变化
- 解耦设计:减少抽象和实现之间的耦合
模式结构
- Abstraction(抽象类):定义抽象类的接口,维护一个实现类对象的引用
- RefinedAbstraction(扩充抽象类):扩充抽象类,改变和修正父类对抽象的定义
- Implementor(实现类接口):定义实现类的接口,不一定要与抽象类的接口完全一致
- ConcreteImplementor(具体实现类):实现实现类接口,定义具体的实现
核心流程
桥接模式流程图
基本实现流程
1. 定义实现类接口
// 实现类接口
public interface Implementor {
void operationImpl();
}
2. 实现具体实现类
// 具体实现类A
public class ConcreteImplementorA implements Implementor {
@Override
public void operationImpl() {
System.out.println("具体实现A的操作");
}
}
// 具体实现类B
public class ConcreteImplementorB implements Implementor {
@Override
public void operationImpl() {
System.out.println("具体实现B的操作");
}
}
3. 定义抽象类
// 抽象类
public abstract class Abstraction {
protected Implementor implementor;
public Abstraction(Implementor implementor) {
this.implementor = implementor;
}
public void setImplementor(Implementor implementor) {
this.implementor = implementor;
}
public abstract void operation();
}
4. 实现扩充抽象类
// 扩充抽象类A
public class RefinedAbstractionA extends Abstraction {
public RefinedAbstractionA(Implementor implementor) {
super(implementor);
}
@Override
public void operation() {
System.out.println("扩充抽象类A的操作");
implementor.operationImpl();
}
}
// 扩充抽象类B
public class RefinedAbstractionB extends Abstraction {
public RefinedAbstractionB(Implementor implementor) {
super(implementor);
}
@Override
public void operation() {
System.out.println("扩充抽象类B的操作");
implementor.operationImpl();
}
}
5. 客户端使用
public class Client {
public static void main(String[] args) {
// 创建具体实现
Implementor implementorA = new ConcreteImplementorA();
Implementor implementorB = new ConcreteImplementorB();
// 创建扩充抽象类
Abstraction abstractionA = new RefinedAbstractionA(implementorA);
Abstraction abstractionB = new RefinedAbstractionB(implementorB);
// 执行操作
abstractionA.operation();
abstractionB.operation();
// 运行时切换实现
abstractionA.setImplementor(implementorB);
abstractionA.operation();
}
}
重难点分析
重难点1:抽象与实现的分离
问题描述
如何正确分离抽象部分和实现部分,避免它们之间的强耦合。
解决方案
// 1. 定义清晰的接口边界
public interface MessageSender {
void send(String message, String recipient);
boolean isAvailable();
}
public interface MessageFormatter {
String format(String message);
String getFormatType();
}
// 2. 抽象类只依赖接口
public abstract class MessageService {
protected MessageSender sender;
protected MessageFormatter formatter;
public MessageService(MessageSender sender, MessageFormatter formatter) {
this.sender = sender;
this.formatter = formatter;
}
public abstract void sendMessage(String message, String recipient);
// 可以运行时切换实现
public void setSender(MessageSender sender) {
this.sender = sender;
}
public void setFormatter(MessageFormatter formatter) {
this.formatter = formatter;
}
}
// 3. 具体实现完全独立
public class EmailSender implements MessageSender {
@Override
public void send(String message, String recipient) {
System.out.println("发送邮件到 " + recipient + ": " + message);
}
@Override
public boolean isAvailable() {
return true;
}
}
public class SMSFormatter implements MessageFormatter {
@Override
public String format(String message) {
return "[SMS] " + message;
}
@Override
public String getFormatType() {
return "SMS";
}
}
重难点2:多维度变化的管理
问题描述
当系统有多个变化维度时,如何避免类爆炸问题。
解决方案
// 1. 识别变化维度
// 维度1:消息类型(文本、图片、视频)
// 维度2:发送方式(邮件、短信、推送)
// 2. 定义各维度的接口
public interface MessageType {
void process();
String getTypeName();
}
public interface DeliveryMethod {
void deliver(String content, String recipient);
boolean isSupported(String recipient);
}
// 3. 使用桥接模式组合
public class MessageProcessor {
private MessageType messageType;
private DeliveryMethod deliveryMethod;
public MessageProcessor(MessageType messageType, DeliveryMethod deliveryMethod) {
this.messageType = messageType;
this.deliveryMethod = deliveryMethod;
}
public void processAndDeliver(String content, String recipient) {
if (deliveryMethod.isSupported(recipient)) {
messageType.process();
deliveryMethod.deliver(content, recipient);
} else {
System.out.println("不支持的发送方式");
}
}
}
// 4. 具体实现
public class TextMessage implements MessageType {
@Override
public void process() {
System.out.println("处理文本消息");
}
@Override
public String getTypeName() {
return "文本";
}
}
public class EmailDelivery implements DeliveryMethod {
@Override
public void deliver(String content, String recipient) {
System.out.println("通过邮件发送: " + content + " 到 " + recipient);
}
@Override
public boolean isSupported(String recipient) {
return recipient.contains("@");
}
}
重难点3:运行时动态切换
问题描述
如何在运行时动态切换不同的实现,而不需要重新创建对象。
解决方案
// 1. 支持动态切换的抽象类
public abstract class ConfigurableService {
protected ServiceImplementation implementation;
public ConfigurableService(ServiceImplementation implementation) {
this.implementation = implementation;
}
public void switchImplementation(ServiceImplementation newImplementation) {
this.implementation = newImplementation;
onImplementationChanged();
}
protected abstract void onImplementationChanged();
public abstract void performOperation();
}
// 2. 实现类接口
public interface ServiceImplementation {
void execute();
String getImplementationName();
}
// 3. 具体实现
public class DatabaseImplementation implements ServiceImplementation {
@Override
public void execute() {
System.out.println("使用数据库实现");
}
@Override
public String getImplementationName() {
return "数据库";
}
}
public class FileImplementation implements ServiceImplementation {
@Override
public void execute() {
System.out.println("使用文件实现");
}
@Override
public String getImplementationName() {
return "文件";
}
}
// 4. 扩充抽象类
public class DataService extends ConfigurableService {
public DataService(ServiceImplementation implementation) {
super(implementation);
}
@Override
protected void onImplementationChanged() {
System.out.println("实现已切换到: " + implementation.getImplementationName());
}
@Override
public void performOperation() {
System.out.println("执行数据操作...");
implementation.execute();
}
}
// 5. 使用示例
public class Client {
public static void main(String[] args) {
DataService service = new DataService(new DatabaseImplementation());
service.performOperation();
// 运行时切换实现
service.switchImplementation(new FileImplementation());
service.performOperation();
}
}
重难点4:桥接模式与策略模式的区别
问题描述
桥接模式和策略模式在结构上相似,如何区分它们的使用场景。
解决方案
// 桥接模式:关注抽象和实现的分离
public class Shape {
protected Color color; // 实现部分
public Shape(Color color) {
this.color = color;
}
public abstract void draw();
}
public class Circle extends Shape {
public Circle(Color color) {
super(color);
}
@Override
public void draw() {
System.out.println("绘制圆形,颜色: " + color.getColorName());
}
}
// 策略模式:关注算法的封装和切换
public class Context {
private Strategy strategy;
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public void executeStrategy() {
strategy.execute();
}
}
public class QuickSortStrategy implements Strategy {
@Override
public void execute() {
System.out.println("使用快速排序");
}
}
// 关键区别:
// 1. 桥接模式:抽象和实现是独立的,可以独立变化
// 2. 策略模式:算法是策略,可以动态切换
// 3. 桥接模式:关注结构分离
// 4. 策略模式:关注行为封装
Spring中的源码分析
DataSource接口的桥接模式应用
// DataSource接口作为抽象
public interface DataSource extends CommonDataSource, Wrapper {
Connection getConnection() throws SQLException;
Connection getConnection(String username, String password) throws SQLException;
}
// 具体实现类
public class HikariDataSource extends HikariConfig implements DataSource, Closeable {
private final HikariPool pool;
public HikariDataSource() {
super();
this.pool = null;
}
public HikariDataSource(HikariConfig configuration) {
configuration.validate();
configuration.copyStateTo(this);
this.pool = new HikariPool(this);
}
@Override
public Connection getConnection() throws SQLException {
if (isClosed()) {
throw new SQLException("HikariDataSource " + this + " has been closed.");
}
if (fastPathPool != null) {
return fastPathPool.getConnection();
}
HikariPool result = pool;
if (result == null) {
synchronized (this) {
result = pool;
if (result == null) {
validate();
result = new HikariPool(this);
this.pool = result;
}
}
}
return result.getConnection();
}
}
// 其他数据源实现
public class DruidDataSource extends DruidAbstractDataSource implements DataSource {
@Override
public Connection getConnection() throws SQLException {
return getConnection(username, password);
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
return getConnectionInternal(username, password);
}
}
Spring JDBC中的桥接模式
// JdbcTemplate作为抽象
public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
private PreparedStatementCreatorFactory preparedStatementCreatorFactory;
private boolean lazyInit = true;
public JdbcTemplate() {
}
public JdbcTemplate(DataSource dataSource) {
setDataSource(dataSource);
afterPropertiesSet();
}
@Override
public <T> T query(String sql, ResultSetExtractor<T> rse) throws DataAccessException {
return query(sql, rse, (Object[]) null);
}
@Override
public <T> T query(String sql, Object[] args, ResultSetExtractor<T> rse) throws DataAccessException {
return query(sql, args, rse, getFetchSize());
}
}
// 具体实现
public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations {
private JdbcOperations classicJdbcTemplate;
public NamedParameterJdbcTemplate(DataSource dataSource) {
this.classicJdbcTemplate = new JdbcTemplate(dataSource);
}
public NamedParameterJdbcTemplate(JdbcOperations classicJdbcTemplate) {
this.classicJdbcTemplate = classicJdbcTemplate;
}
@Override
public <T> T query(String sql, Map<String, ?> paramMap, ResultSetExtractor<T> rse) throws DataAccessException {
return getJdbcOperations().query(sql, rse, getPreparedStatementCreator(sql, paramMap));
}
}
Spring MVC中的桥接模式
// ViewResolver接口作为抽象
public interface ViewResolver {
View resolveViewName(String viewName, Locale locale) throws Exception;
}
// 具体实现
public class InternalResourceViewResolver extends UrlBasedViewResolver {
private String prefix = "";
private String suffix = "";
public InternalResourceViewResolver() {
setViewClass(InternalResourceView.class);
}
@Override
protected AbstractUrlBasedView buildView(String viewName) throws Exception {
InternalResourceView view = (InternalResourceView) super.buildView(viewName);
if (this.prefix != null && this.suffix != null && view.getBeanName() != null) {
view.setUrl(this.prefix + view.getBeanName() + this.suffix);
}
return view;
}
}
// 另一个实现
public class FreeMarkerViewResolver extends AbstractTemplateViewResolver {
public FreeMarkerViewResolver() {
setViewClass(FreeMarkerView.class);
}
@Override
protected AbstractUrlBasedView buildView(String viewName) throws Exception {
FreeMarkerView view = (FreeMarkerView) super.buildView(viewName);
view.setExposeRequestAttributes(true);
view.setExposeSessionAttributes(true);
view.setExposeSpringMacroHelpers(true);
return view;
}
}
Spring Security中的桥接模式
// AuthenticationManager接口
public interface AuthenticationManager {
Authentication authenticate(Authentication authentication) throws AuthenticationException;
}
// 具体实现
public class ProviderManager implements AuthenticationManager, MessageSourceAware, InitializingBean {
private List<AuthenticationProvider> providers = Collections.emptyList();
private AuthenticationManager parent;
public ProviderManager(List<AuthenticationProvider> providers) {
this(providers, null);
}
public ProviderManager(List<AuthenticationProvider> providers, AuthenticationManager parent) {
this.providers = providers;
this.parent = parent;
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
Class<? extends Authentication> toTest = authentication.getClass();
AuthenticationException lastException = null;
AuthenticationException parentException = null;
Authentication result = null;
Authentication parentResult = null;
for (AuthenticationProvider provider : getProviders()) {
if (!provider.supports(toTest)) {
continue;
}
try {
result = provider.authenticate(authentication);
if (result != null) {
copyDetails(authentication, result);
break;
}
} catch (AuthenticationException ex) {
lastException = ex;
}
}
if (result == null && parent != null) {
try {
result = parentResult = parent.authenticate(authentication);
} catch (ProviderNotFoundException ex) {
// 忽略
} catch (AuthenticationException ex) {
parentException = lastException = ex;
}
}
if (result != null) {
if (eraseCredentialsAfterAuthentication && (result instanceof CredentialsContainer)) {
((CredentialsContainer) result).eraseCredentials();
}
eventPublisher.publishAuthenticationSuccess(result);
return result;
}
if (lastException == null) {
lastException = new ProviderNotFoundException("ProviderManager.authenticate: No AuthenticationProvider found for " + toTest.getName());
}
prepareException(lastException, authentication);
throw lastException;
}
}
具体使用场景
1. 图形绘制系统
// 实现类接口
public interface DrawingAPI {
void drawCircle(double x, double y, double radius);
void drawRectangle(double x, double y, double width, double height);
}
// 具体实现
public class WindowsDrawingAPI implements DrawingAPI {
@Override
public void drawCircle(double x, double y, double radius) {
System.out.println("Windows API: 绘制圆形 at (" + x + "," + y + ") radius " + radius);
}
@Override
public void drawRectangle(double x, double y, double width, double height) {
System.out.println("Windows API: 绘制矩形 at (" + x + "," + y + ") size " + width + "x" + height);
}
}
public class LinuxDrawingAPI implements DrawingAPI {
@Override
public void drawCircle(double x, double y, double radius) {
System.out.println("Linux API: 绘制圆形 at (" + x + "," + y + ") radius " + radius);
}
@Override
public void drawRectangle(double x, double y, double width, double height) {
System.out.println("Linux API: 绘制矩形 at (" + x + "," + y + ") size " + width + "x" + height);
}
}
// 抽象类
public abstract class Shape {
protected DrawingAPI drawingAPI;
protected Shape(DrawingAPI drawingAPI) {
this.drawingAPI = drawingAPI;
}
public abstract void draw();
public abstract void resize(double factor);
}
// 扩充抽象类
public class Circle extends Shape {
private double x, y, radius;
public Circle(double x, double y, double radius, DrawingAPI drawingAPI) {
super(drawingAPI);
this.x = x;
this.y = y;
this.radius = radius;
}
@Override
public void draw() {
drawingAPI.drawCircle(x, y, radius);
}
@Override
public void resize(double factor) {
radius *= factor;
}
}
public class Rectangle extends Shape {
private double x, y, width, height;
public Rectangle(double x, double y, double width, double height, DrawingAPI drawingAPI) {
super(drawingAPI);
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
@Override
public void draw() {
drawingAPI.drawRectangle(x, y, width, height);
}
@Override
public void resize(double factor) {
width *= factor;
height *= factor;
}
}
// 客户端使用
public class Client {
public static void main(String[] args) {
DrawingAPI windowsAPI = new WindowsDrawingAPI();
DrawingAPI linuxAPI = new LinuxDrawingAPI();
Shape circle1 = new Circle(1, 2, 3, windowsAPI);
Shape circle2 = new Circle(5, 7, 11, linuxAPI);
circle1.draw();
circle2.draw();
// 运行时切换实现
circle1 = new Circle(1, 2, 3, linuxAPI);
circle1.draw();
}
}
2. 消息发送系统
// 消息发送接口
public interface MessageSender {
void send(String message, String recipient);
boolean isAvailable();
}
// 具体实现
public class EmailSender implements MessageSender {
@Override
public void send(String message, String recipient) {
System.out.println("发送邮件到 " + recipient + ": " + message);
}
@Override
public boolean isAvailable() {
return true;
}
}
public class SMSSender implements MessageSender {
@Override
public void send(String message, String recipient) {
System.out.println("发送短信到 " + recipient + ": " + message);
}
@Override
public boolean isAvailable() {
return true;
}
}
// 消息格式化接口
public interface MessageFormatter {
String format(String message);
}
// 具体格式化实现
public class HTMLFormatter implements MessageFormatter {
@Override
public String format(String message) {
return "<html><body>" + message + "</body></html>";
}
}
public class PlainTextFormatter implements MessageFormatter {
@Override
public String format(String message) {
return message;
}
}
// 抽象消息服务
public abstract class MessageService {
protected MessageSender sender;
protected MessageFormatter formatter;
public MessageService(MessageSender sender, MessageFormatter formatter) {
this.sender = sender;
this.formatter = formatter;
}
public abstract void sendMessage(String message, String recipient);
public void setSender(MessageSender sender) {
this.sender = sender;
}
public void setFormatter(MessageFormatter formatter) {
this.formatter = formatter;
}
}
// 具体消息服务
public class NotificationService extends MessageService {
public NotificationService(MessageSender sender, MessageFormatter formatter) {
super(sender, formatter);
}
@Override
public void sendMessage(String message, String recipient) {
if (sender.isAvailable()) {
String formattedMessage = formatter.format(message);
sender.send(formattedMessage, recipient);
} else {
System.out.println("发送服务不可用");
}
}
}
3. 数据库访问层
// 数据库连接接口
public interface DatabaseConnection {
void connect();
void disconnect();
void execute(String sql);
boolean isConnected();
}
// 具体实现
public class MySQLConnection implements DatabaseConnection {
@Override
public void connect() {
System.out.println("连接到MySQL数据库");
}
@Override
public void disconnect() {
System.out.println("断开MySQL数据库连接");
}
@Override
public void execute(String sql) {
System.out.println("MySQL执行SQL: " + sql);
}
@Override
public boolean isConnected() {
return true;
}
}
public class PostgreSQLConnection implements DatabaseConnection {
@Override
public void connect() {
System.out.println("连接到PostgreSQL数据库");
}
@Override
public void disconnect() {
System.out.println("断开PostgreSQL数据库连接");
}
@Override
public void execute(String sql) {
System.out.println("PostgreSQL执行SQL: " + sql);
}
@Override
public boolean isConnected() {
return true;
}
}
// 抽象数据访问类
public abstract class DataAccessObject {
protected DatabaseConnection connection;
public DataAccessObject(DatabaseConnection connection) {
this.connection = connection;
}
public abstract void save(Object entity);
public abstract void delete(Object entity);
public abstract Object findById(Object id);
public void setConnection(DatabaseConnection connection) {
this.connection = connection;
}
}
// 具体数据访问类
public class UserDAO extends DataAccessObject {
public UserDAO(DatabaseConnection connection) {
super(connection);
}
@Override
public void save(Object entity) {
connection.execute("INSERT INTO users VALUES (" + entity + ")");
}
@Override
public void delete(Object entity) {
connection.execute("DELETE FROM users WHERE id = " + entity);
}
@Override
public Object findById(Object id) {
connection.execute("SELECT * FROM users WHERE id = " + id);
return "User with id: " + id;
}
}
4. 文件处理系统
// 文件存储接口
public interface FileStorage {
void save(String filename, byte[] data);
byte[] load(String filename);
void delete(String filename);
boolean exists(String filename);
}
// 具体实现
public class LocalFileStorage implements FileStorage {
private String basePath;
public LocalFileStorage(String basePath) {
this.basePath = basePath;
}
@Override
public void save(String filename, byte[] data) {
System.out.println("保存文件到本地: " + basePath + "/" + filename);
}
@Override
public byte[] load(String filename) {
System.out.println("从本地加载文件: " + basePath + "/" + filename);
return new byte[0];
}
@Override
public void delete(String filename) {
System.out.println("删除本地文件: " + basePath + "/" + filename);
}
@Override
public boolean exists(String filename) {
return true;
}
}
public class CloudFileStorage implements FileStorage {
private String bucketName;
public CloudFileStorage(String bucketName) {
this.bucketName = bucketName;
}
@Override
public void save(String filename, byte[] data) {
System.out.println("保存文件到云存储: " + bucketName + "/" + filename);
}
@Override
public byte[] load(String filename) {
System.out.println("从云存储加载文件: " + bucketName + "/" + filename);
return new byte[0];
}
@Override
public void delete(String filename) {
System.out.println("删除云存储文件: " + bucketName + "/" + filename);
}
@Override
public boolean exists(String filename) {
return true;
}
}
// 文件处理接口
public interface FileProcessor {
void process(String filename, byte[] data);
String getSupportedFormat();
}
// 具体处理器
public class ImageProcessor implements FileProcessor {
@Override
public void process(String filename, byte[] data) {
System.out.println("处理图片文件: " + filename);
}
@Override
public String getSupportedFormat() {
return "jpg,png,gif";
}
}
public class DocumentProcessor implements FileProcessor {
@Override
public void process(String filename, byte[] data) {
System.out.println("处理文档文件: " + filename);
}
@Override
public String getSupportedFormat() {
return "pdf,doc,docx";
}
}
// 抽象文件服务
public abstract class FileService {
protected FileStorage storage;
protected FileProcessor processor;
public FileService(FileStorage storage, FileProcessor processor) {
this.storage = storage;
this.processor = processor;
}
public abstract void handleFile(String filename, byte[] data);
public void setStorage(FileStorage storage) {
this.storage = storage;
}
public void setProcessor(FileProcessor processor) {
this.processor = processor;
}
}
// 具体文件服务
public class MediaFileService extends FileService {
public MediaFileService(FileStorage storage, FileProcessor processor) {
super(storage, processor);
}
@Override
public void handleFile(String filename, byte[] data) {
if (storage.exists(filename)) {
byte[] existingData = storage.load(filename);
processor.process(filename, existingData);
} else {
storage.save(filename, data);
processor.process(filename, data);
}
}
}
面试高频点
面试知识点思维导图
1. 桥接模式的基本概念
问题:什么是桥接模式?
答案要点:
- 将抽象部分与实现部分分离,使它们可以独立地变化
- 使用组合关系而不是继承关系
- 属于结构型设计模式
- 解决类爆炸问题
问题:桥接模式有哪些角色?
答案要点:
- Abstraction(抽象类):定义抽象类的接口,维护实现类对象的引用
- RefinedAbstraction(扩充抽象类):扩充抽象类,改变和修正父类对抽象的定义
- Implementor(实现类接口):定义实现类的接口
- ConcreteImplementor(具体实现类):实现实现类接口,定义具体的实现
2. 实现方式相关
问题:如何实现桥接模式?
答案要点:
// 1. 定义实现类接口
public interface Implementor {
void operationImpl();
}
// 2. 实现具体实现类
public class ConcreteImplementorA implements Implementor {
@Override
public void operationImpl() {
System.out.println("具体实现A");
}
}
// 3. 定义抽象类
public abstract class Abstraction {
protected Implementor implementor;
public Abstraction(Implementor implementor) {
this.implementor = implementor;
}
public abstract void operation();
}
// 4. 实现扩充抽象类
public class RefinedAbstraction extends Abstraction {
public RefinedAbstraction(Implementor implementor) {
super(implementor);
}
@Override
public void operation() {
implementor.operationImpl();
}
}
3. 重难点问题
问题:桥接模式如何解决类爆炸问题?
答案要点:
- 问题:当系统有多个变化维度时,使用继承会导致类数量急剧增长
- 解决:使用组合关系将多个变化维度分离
- 示例:图形系统有形状和颜色两个维度,使用桥接模式可以避免形状×颜色的类爆炸
问题:桥接模式与策略模式的区别?
答案要点:
- 目的:桥接模式关注抽象和实现的分离,策略模式关注算法的封装
- 结构:桥接模式有抽象和实现两个层次,策略模式只有一个层次
- 变化:桥接模式支持多个维度的独立变化,策略模式支持算法的动态切换
- 使用场景:桥接模式用于结构分离,策略模式用于行为封装
4. Spring中的应用
问题:Spring中如何使用桥接模式?
答案要点:
// 1. DataSource接口的桥接模式
public interface DataSource extends CommonDataSource, Wrapper {
Connection getConnection() throws SQLException;
}
// 2. JdbcTemplate的桥接模式
public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
private DataSource dataSource;
public JdbcTemplate(DataSource dataSource) {
setDataSource(dataSource);
}
}
// 3. ViewResolver的桥接模式
public interface ViewResolver {
View resolveViewName(String viewName, Locale locale) throws Exception;
}
5. 设计原则相关
问题:桥接模式体现了哪些设计原则?
答案要点:
- 开闭原则:对扩展开放,对修改关闭
- 单一职责:抽象和实现各司其职
- 依赖倒置:依赖抽象而不是具体实现
- 组合优于继承:使用组合关系而不是继承关系
6. 实际应用场景
问题:桥接模式适用于哪些场景?
答案要点:
- 图形绘制:形状和绘制API的分离
- 消息发送:消息类型和发送方式的分离
- 数据库访问:数据访问对象和数据库连接的分离
- 文件处理:文件类型和存储方式的分离
- 多平台支持:业务逻辑和平台实现的分离
7. 与其他模式的对比
问题:桥接模式与适配器模式的区别?
答案要点:
- 目的:桥接模式是设计时模式,适配器模式是运行时模式
- 关系:桥接模式是抽象和实现的分离,适配器模式是接口的转换
- 使用时机:桥接模式在系统设计时使用,适配器模式在系统集成时使用
问题:桥接模式与装饰器模式的区别?
答案要点:
- 目的:桥接模式是结构分离,装饰器模式是功能增强
- 关系:桥接模式是组合关系,装饰器模式是包装关系
- 变化:桥接模式支持独立变化,装饰器模式支持功能叠加
总结
桥接模式是一种重要的结构型设计模式,它通过将抽象部分与实现部分分离,实现了它们之间的解耦,并支持独立的变化。
核心优势
- 解耦:抽象和实现分离,降低耦合度
- 扩展性:支持多个维度的独立变化
- 灵活性:可以在运行时切换实现
- 可维护性:抽象和实现可以独立修改
注意事项
- 复杂度:增加了系统的复杂度
- 理解成本:需要理解抽象和实现的关系
- 过度设计:简单场景可能不需要使用
- 性能考虑:组合关系可能影响性能
在实际开发中,桥接模式特别适用于有多个变化维度、需要支持多平台、或者需要解耦抽象和实现的场景。通过合理使用桥接模式,可以大大提高系统的灵活性和可维护性。
531

被折叠的 条评论
为什么被折叠?



