设计模式(一)——设计原则

  在一定环境下,用固定模式解决问题。

  设计模式目前种类:GoF的23种 + “简单工厂模式” = 24

  包括:

  创建型(Creational)模式:如何创建对象,6种

  结构性(Structual)模式:如何实现类或对象的组合,7种

  行为型(Behavioral)模式:类或对象怎样交互以及怎样分配职责,11种

 

学习设计模式有利于更深理解面向对象思想,让你知道:

  1.如何将代码分散在几个不同的类中?

  2.为什么要有“接口”

  3.何胃针对抽象编程

  4.何时不应该使用继承?

  5.如果不修改源代码增加新功能?

  6.更好低阅读和理解现有类库与其他系统中的源代码?

  

设计模式的基础:多态(继承,虚函数重写,父类指针或引用指向子类对象)

 

原则:

  对于面向对象软件系统的设计而言,在支持可维护性的同时,提高系统的
可复用性是一个至关重要的问题,
如何同时提高一个软件系统的可维护性和可
复用性是面向对象设计需要解决的核心问题之一。 在面向对象设计中,可维护
性的复用是以设计原则为基础的。每一个原则都蕴含一些面向对象设计的思想,
可以从不同的角度提升一个软件结构的设计水平。
  面向对象设计原则为支持可维护性复用而诞生,这些原则蕴含在很多设计
模式中,它们是从许多设计方案中总结出的指导性原则。 面向对象设计原则也
是我们用于评价一个设计模式的使用效果的重要指标之一。
   


  目标:高内聚,低耦合

 


  单一职责原则:类的职责单一,对外只提供一种功能

    将每个类的方法分离出来,就能保证每个类的指针单一

    提高安全性

    提高了维护性

    提高了可读性

     

#include <iostream>

using namespace std;

class Clothes
{
public:
    void shopping()
    {
        cout << "休闲的衣服" << endl;
    }
    void working()
    {
        cout << "工作的衣服" << endl;
    }
};

class ClothesShoping
{
public:
    void style()
    {
        cout << "休闲的衣服" << endl;
    }
};

class ClothesWorking
{
public:
    void style()
    {
        cout << "工作的衣服" << endl;
    }
};

int main()
{
    ClothesShoping cs;
    cs.style();

    ClothesWorking cw;
    cw.style();

    system("pause");
    return 0;
}

 

    开闭原则:类的改动是通过增加代码进行的,而不是修改源代码

        提高了可读性

        提高了安全性

        提高了维护性

        提高了可复用性

 

#include <iostream>

using namespace std;




// 银行业务员:
class Banker
{
public:
    void save()
    {
        cout << "存款" << endl;
    }
    void pay()
    {
        cout << "支付" << endl;
    }
    void tansfer()
    {
        cout << "转账" << endl;
    }
    // 添加一个办理基金业务 若添加的业务多,则代码会越来越庞大
    void fund() 
    {
        cout << "办理基金" << endl;
    }
};

/////////////////////////////////
//////////////////////////////////
// 抽象的银行业务员
//-------------------------------
//-   worker() = 0              -
//-                             -
//-------------------------------
/////////////////////////////////

//////////////////////////////////
// 存款业务员
//-------------------------------
//-                             -
//-     存款                    -
//-------------------------------
/////////////////////////////////
//////////////////////////////////
// 支付业务员
//-------------------------------
//-   支付                      -
//-                             -
//-------------------------------
/////////////////////////////////
//////////////////////////////////
// 转账业务员
//-------------------------------
//-   转账                      -
//-                             -
//-------------------------------
/////////////////////////////////

// 抽象类
// 添加新的业务不需要修改原来代码,只需要添加新代码
class AbstractBanker
{
public:
    virtual void worker() = 0;// 抽象接口
};

class SaveBanker:public AbstractBanker
{
public:
    virtual void worker()
    {
        cout << "存款" << endl;
    }
};

class PayBanker :public AbstractBanker
{
public:
    virtual void worker()
    {
        cout << "支付" << endl;
    }
};

class TransferBanker :public AbstractBanker
{
public:
    virtual void worker()
    {
        cout << "转账" << endl;
    }
};

// 添加一个办理基金业务 若添加的业务多,则代码会越来越庞大
class FundBanker :public AbstractBanker
{
public:
    virtual void worker()
    {
        cout << "基金业务" << endl;
    }
};

int main()
{
#if 0 // 此方法不好
    Banker b;
    b.save();
#endif

    AbstractBanker* ab = new SaveBanker();
    ab->worker();
    ab = new PayBanker();
    ab->worker();
    ab = new TransferBanker();
    ab->worker();

    delete ab;
    system("pause");
    return 0;
}

 

 

    依赖倒转原则:依赖于抽象(借口),不要依赖于具体实现(类),也就是针对接口编程

        将业务层和实现层通过抽象层隔离——解耦合   

#include <iostream>
using namespace std;

class Benz
{
public:
    void run()
    {
        cout << "奔驰启动了" << endl;
    }
};

class Baoma
{
public:
    void run()
    {
        cout << "宝马启动了" << endl;
    }
};

class Zhangsan
{
public:
    void driveBenz(Benz* b)
    {
        b->run();
    }
    void driveBMW(Baoma* b)
    {
        b->run();
    }
};

///////////////////////////////////////
// 高层业务逻辑层
//
///////////////////////////////////////

///////////////////////////////////////
// 抽象层
// Driver                   Car
///////////////////////////////////////

///////////////////////////////////////
// 实现层      底层向上依赖
// zhangsan     lisi        baoma benz
///////////////////////////////////////

// 抽象层
class Car
{
public:
    virtual void run() = 0;
};

class Driver
{
public:
    virtual void driver(Car* car) = 0;
};


class Jeep:public Car
{
public:
    virtual void run()
    {
        cout << "吉普启动了" << endl;
    }
};

class Lisi :public Driver
{
public:
    virtual void driver(Car* car)
    {
        cout << "李四开车了" << endl;
        car->run();
    }
};

// 业务
int main()
{
#if 0
    // 让zhangsan 去开benz
    Benz* benz = new Benz;
    Zhangsan* zhangsan = new Zhangsan;
    zhangsan->driveBenz(benz);

    // 让zhangsan 去开benz
    Baoma* BMW = new Baoma;
    zhangsan->driveBMW(BMW);

    // 去开大众,jeep...越写越复杂混乱

    delete benz;
    delete BMW;
    delete zhangsan;
#endif
    // 只使用两个类
    Car* car = new Jeep;
    Driver* lisi = new Lisi;

    lisi->driver(car);

    delete car;
    delete lisi;
    system("pause");
    return 0;
}

 

    合成复用原则:如果使用继承,会导致父类的任何变换都影响到子类的行为。如果使用对                     象组合,就降低了这种依赖关系。对于继承和组合,优先使用组合。

          如果使用继承方式,那么新的子类将会和所有的父类高耦合

 

#include <iostream>
using namespace std;

class Cat // 还可以继承动物...
{
public:
    void sleep()
    {
        cout << "小猫睡觉" << endl;
    }
};

// 继承方式
class AdCat :public Cat
{
public:
    void eat_and_sleep()
    {
        cout << "吃东西" << endl;
        sleep();
    }
};

// 使用组合的方式来添加小猫吃东西的方法
// 降低了AdCat2和Cat的耦合度,跟Cat的父类没有任何关系
// 只跟Cat的sleep方法有关系
class AdCat2
{
public:
     AdCat2(Cat* cat)
    {
         this->cat = cat;
    }
     void eat_and_sleep()// 若将cat以参数传入,则是依赖关系
     {
         cout << "吃东西" << endl;
         cat->sleep();
     }
private:
    Cat* cat;// 这种关系是关联
};

int main()
{
    Cat cat;
    AdCat2 adcat(&cat);
    adcat.eat_and_sleep();
    system("pause");
    return 0;
}

 

posted @ 2019-02-08 19:32  狂奔~  阅读(364)  评论(0编辑  收藏  举报