设计模式--桥接模式

设计模式--桥接模式,第1张

class="superseo">设计模式–桥接模式(Bridge) 1.定义

桥接模式:将抽象部分与它的实现部分分离,使它们可以独立地变化。


2.实例

设想如果要绘制矩形、圆形、椭圆、正方形,我们至少需要4个形状类,但是如果绘制的图形需要具有不同的颜色,
如红色、绿色、蓝色等,此时至少有如下两种设计方案:

  • 第一种设计方案是为每一种形状都提供一套各种颜色的版本;
  • 第二种设计方案是根据实际需要对形状和颜色进行组合。



    对于有两个变化维度(即两个变化的原因)的系统,采用方案二来进行设计系统中类的个数更少,且系统扩展更为方便。



    设计方案二即是桥接模式的应用。


    桥接模式将继承关系转换为关联关系,从而降低了类与类之间的耦合,减少了代码编写量。


3.模式结构

桥接模式包含如下角色:

  • shape:图形抽象类
  • retangle,circle:图形扩充抽象类
  • color:颜色实现类接口
  • red,yellow:具体颜色实现类

4.代码分析
  • 4.1 c++代码实现
  • 4.1.1 main.cpp
/**
 * @file main.cpp
 * @brief 
 * @version 0.1
 * @date 2022-04-02
 * 
 * @copyright Copyright (c) 2022
 * 
 */

#include
#include"shape.hpp"
#include"color.hpp"
using namespace std;


void test_inline_bridge() {
    color* clr = new yellow();
    shape* shp = new circle(clr);
    

    shp->draw(); 
    cout << "-----------------------" << endl;

    clr = new red();
    shp = new circle(clr);
    shp->draw();
    cout << "-----------------------" << endl;
    
    clr = new red();
    shp = new retangle(clr);
    shp->draw();
    cout << "-----------------------" << endl;

    clr = new yellow();
    shp = new retangle(clr);
    shp->draw();
    cout << "-----------------------" << endl;
}

int main(int argc, const char** argv) {
    test_inline_bridge();

    return 0;
}
  • 4.1.2 color.hpp
//===========================================================
/**
 * @file color.hpp
 * @brief 
 * @version 0.1
 * @date 2022-04-02
 * 
 * @copyright Copyright (c) 2022
 * 
 */

#ifndef D50611F4_86D1_48F4_BCA6_3AFD4AE61BAC
#define D50611F4_86D1_48F4_BCA6_3AFD4AE61BAC

#include<iostream>
using namespace std;

// 颜色抽象接口
class color
{
public:
    color(){};
    virtual ~color(){};
    virtual void choose_color(){};
};


class red: public color {
public:
    red(){};
    ~red(){};

    void choose_color(){
        cout << "choose_color red" << endl;
    };
};

class yellow: public color {
public:
    yellow(){};
    ~yellow(){};

    void choose_color(){
        cout << "choose_color yellow" << endl;
    };
};

class blue: public color {
public:
    blue(){};
    ~blue(){};

    void choose_color(){
        cout << "choose_color blue" << endl;
    };
};

#endif /* D50611F4_86D1_48F4_BCA6_3AFD4AE61BAC */
  • 4.1.3 shape.hpp
//===========================================================
/**
 * @file shape.hpp
 * @brief 
 * @version 0.1
 * @date 2022-04-02
 * 
 * @copyright Copyright (c) 2022
 * 
 */

#ifndef F45EC17B_C10E_4F7B_A409_1D60017EF5CE
#define F45EC17B_C10E_4F7B_A409_1D60017EF5CE

#include <iostream>
#include"color.hpp"

using namespace std;

// 图形抽象接口
class shape {
private: 
    color* m_clr;
protected:
    color* get_clr() {
        return m_clr;
    }
public:
    shape(color* clr): m_clr(clr) {};
    virtual ~shape(){
        delete m_clr;
    };

    virtual void draw(){};
};


class circle: public shape
{
public:
    circle(color* clr): shape(clr){};
    ~circle(){};

    void draw(){
        cout << "circle::draw" << endl;
        get_clr()->choose_color();
    }
};

class retangle: public shape
{
public:
    retangle(color* clr):shape(clr){};
    ~retangle(){};
    void draw(){
        cout << "retangle::draw" << endl;
        get_clr()->choose_color();
    }
};

class triangle: public shape
{
public:
    triangle(color* clr):shape(clr){};
    ~triangle(){};
    void draw(){
        cout << "triangle::draw" << endl;
        get_clr()->choose_color();
    }
};

#endif /* F45EC17B_C10E_4F7B_A409_1D60017EF5CE */
  • 4.2 go代码实现: go实现和c++实现有点不一样, 因为go的接口类不能带有成员变量,故通过参数将其传入,这个安全性没有c++好。


  • 4.3 color.go和shape.go在main.go同一级目录的bridge的包下,代码如下:

  • 4.3.1:color.go

// color.go
package bridge

import (
	"fmt"
)

// ==================================================
// 颜色抽象接口
type IColor interface{
	ChooseColor()
}

// ==================================================

type Red struct {

}

func NewRed() *Red {
	return &Red{}
}

func (r *Red) ChooseColor() {
	fmt.Println("ChooseColor::Red")
}

// ==================================================

type Yellow struct {

}

func NewYellow() *Yellow {
	return &Yellow{}
}

func (y *Yellow) ChooseColor() {
	fmt.Println("ChooseColor::Yellow")
}

// ==================================================

type Blue struct {

}

func NewBlue() *Blue {
	return &Blue{}
}

func (b *Blue) ChooseColor() {
	fmt.Println("ChooseColor::Blue")
}

  • 4.3.2:shape.go
package bridge

import (
	"fmt"
)
// ==================================================
// 图形抽象接口
type IShape interface{
	Draw(clr IColor)
}

// ==================================================

type Circle struct {

}

func NewCircle() *Circle {
	return &Circle{}
}

func (c *Circle) Draw(clr IColor) {
	fmt.Println("Circle::Draw")
	clr.ChooseColor()
	fmt.Println("---------------------------")
}

// ==================================================

type Retangle struct {}

func NewRetangle() *Retangle {
	return &Retangle{}
}

func (r *Retangle) Draw(clr IColor) {
	fmt.Println("Retangle::Draw")
	clr.ChooseColor()
	fmt.Println("---------------------------")
}

  • 4.3.3:main.go
package main

import (
	"./bridge"
)

func main() {
	var ishp bridge.IShape = bridge.NewCircle()

	ishp.Draw(bridge.NewRed())
	ishp.Draw(bridge.NewYellow())
	ishp.Draw(bridge.NewBlue())

	var itshp bridge.IShape = bridge.NewRetangle()

	itshp.Draw(bridge.NewRed())
	itshp.Draw(bridge.NewYellow())
	itshp.Draw(bridge.NewBlue())
}
  • 4.3.3:执行结果:
Circle::Draw
ChooseColor::Red
---------------------------
Circle::Draw
ChooseColor::Yellow
---------------------------
Circle::Draw
ChooseColor::Blue
---------------------------
Retangle::Draw
ChooseColor::Red
---------------------------
Retangle::Draw
ChooseColor::Yellow
---------------------------
Retangle::Draw
ChooseColor::Blue
---------------------------
5.模式分析

理解桥接模式,重点需要理解如何将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化。


  • 抽象化:抽象化就是忽略一些信息,把不同的实体当作同样的实体对待。



    在面向对象中,将对象的共同性质抽取出来形成类的过程即为抽象化的过程。


  • 实现化:针对抽象化给出的具体实现,就是实现化,抽象化与实现化是一对互逆的概念,
    实现化产生的对象比抽象化更具体,是对抽象化事物的进一步具体化的产物。


  • 脱耦:脱耦就是将抽象化和实现化之间的耦合解脱开,或者说是将它们之间的强关联改换成弱关联,
    将两个角色之间的继承关系改为关联关系。


    桥接模式中的所谓脱耦,就是指在一个软件系统的抽象化和实现化之间使用关联关系(组合或者聚合关系)而不是继承关系,
    从而使两者可以相对独立地变化,这就是桥接模式的用意。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/564277.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-03
下一篇 2022-04-03

发表评论

登录后才能评论

评论列表(0条)

保存