我在一定程度上理解了桥接模式。我理解接口和实现的解耦。它使用一个像插件一样的实现类,它包含派生类实现的实际逻辑。
但是有人能解释一下它是如何允许接口和派生独立发展的吗?如果我想向接口添加一个新方法,它必须在派生类中实现,派生类将修改它。
其次,必须修改客户端代码以在需要新对象时设置新的实现者。
我在一定程度上理解了桥接模式。我理解接口和实现的解耦。它使用一个像插件一样的实现类,它包含派生类实现的实际逻辑。
但是有人能解释一下它是如何允许接口和派生独立发展的吗?如果我想向接口添加一个新方法,它必须在派生类中实现,派生类将修改它。
其次,必须修改客户端代码以在需要新对象时设置新的实现者。
是的,Bridge 模式的目的是将抽象(即接口)与实现分离,让它们独立变化。在实践中,这个想法是使用两个独立的层次结构而不是经典的单一层次结构。
让我们举个例子。假设您有一个Window抽象,并且您需要创建一个 IconWindow 子类,该子类专门针对每个支持的平台使用Window 。
使用单一层次结构,您可以获得:
Window
|--------------...
IconWindow
|
-----------------------------------------------...
| | |
XIconWindow MSIconWindow OSXIconWindow
这种结构非常不方便,因为:
如果您想添加一个专门用于Window的新子类(例如BitmapWindow),您必须为每个支持的平台创建一个子类(即本例中的三个子类)。
如果要添加受支持的平台,则必须为每个现有专业化添加新的子类。
因此,最好通过以下方式解耦两个层次结构:
imp
Window--------------------------> WindowImp
| |
-----------.... ---------------------------------
| | | |
IconWindow XWindowImp MSWindowImp OSXWindowImp
Window和WindowImp是接口。IconWindow 使用Window提供的方法。Window反过来调用 imp 的相关方法。
Window和WindowImp之间的关系称为Bridge。
示例:IconWindow::DrawBorder() 使用 Window::DrawRect(),它调用在WindowImp中声明并在具体子类中定义的 imp->DevDrawLine()(例如,在 XWindowImp 类中)。
我的建议是阅读包含上述示例的书:Design patterns - Elements of Reusable Object-Oriented Software”( http://en.wikipedia.org/wiki/Design_Patterns )。
我认为 Java JDBC API 是说明桥接设计模式用户的最佳示例。客户端使用抽象(JDBC API)而不用担心不同 SQL 供应商提供的实现(MYSQL、Oracle 等)。
为了进一步说明,假设您有 EmployeeDAOImpl,它使用保存、更新、删除方法实现 EmployeeDAO 接口。现在,这个 EmployeeDAOImpl 将使用 JDBC API(抽象)来执行 CRUD 操作,而不用担心使用的数据库。EmployeeDAOImpl 唯一需要的是加载驱动程序的 url。
现在的关键是,EmployeeDAOImpl 和其他 DAO 的层次结构可以独立变化。他们不必担心 JDBI API 抽象的实现。
桥接模式:
将抽象与其实现分离,以便两者可以独立变化;
结构模式;
桥接模式是软件工程中使用的一种设计模式,旨在“将抽象与其实现分离,以便两者可以独立变化”。桥接使用封装、聚合,可以使用继承将职责分离到不同的类中;
当一个类经常变化时,面向对象编程的特性就变得非常有用,因为对程序代码的更改可以很容易地在对程序有最少的先验知识的情况下进行。当类以及它的功能经常变化时,桥接模式很有用。类本身可以被认为是实现,而类可以做什么是抽象。桥接模式也可以被认为是两层抽象。
桥接模式经常与适配器模式混淆。事实上,桥接模式通常使用类适配器模式来实现;
变体:通过将实现的存在推迟到使用抽象的点,实现可以进一步解耦。