设计模式六大原则:迪米特原则-带你走进梦幻西游(四)

转载请标明:http://blog.csdn.net/liulongling/article/details/51332685
面向对象其它六大原则
单一职责原则-带你走梦幻西游(一)
依赖倒置原则(二)
开闭原则-带你走进梦幻西游(三)
里氏替换原则(五)
接口隔离原则(六)

迪米特原则英文名称Law of Demeter,缩写LOD,也称为最少知识原则(Least Knowledge Principle).
定义
一个对象应该对其它对象有最少的了解,从而降低各个对象之间的耦合,让程序有更好的可扩展性。

为什么用迪米特原则
下面举例说明,
案例:
玩梦幻西游的玩家知道可以藏宝阁购买游戏中的道具,召唤兽。比如:毛驴我今天刚渡劫,终于可以带狂豹了,于是打开藏宝阁选择召唤兽类型:狂豹,输入等级:169,按下搜索键,系统会把所有169级的狂豹显示出来。接下来毛驴我就开始设计代码结构图。如图:
这里写图片描述

//
//  非迪米特原则.cpp
//  c++
//
//  Created by 刘龙玲 on 16/5/6.
//  Copyright © 2016年 liulongling. All rights reserved.
//

#include <iostream>
#include <string>
#include <set>
#include <list>

using namespace std;

static const string name[] = {"狂豹","律法","雷鸟人","大力金刚","吸血鬼"};

//召唤兽
class Pet
{
public:

    Pet(int id,int lvl,string name)
    {
        this->id = id;
        this->level = lvl;
        this->name = name;
    }
    int getId()
    {
        return this->id;
    }
    int getLevel()
    {
        return this-> level;
    }
    string getName()
    {
        return this->name;
    }
private:
    int id;
    int level;
    string name;
};

//商会
class Commerce
{
public:

    Commerce()
    {
        cout<<"Commerce()"<<endl;
        for(int i=0;i<10;i++)
        {
            Pet pet(1,i+5,name[i]);
            pets.push_back(pet);
        }
        cout<<pets.size()<<endl;
    }

    list<Pet> getPets()
    {
        return this->pets;
    }
private:
    list<Pet> pets;
};

class Player
{
public:
    int id = 1;
    int lvl = 6;
    void buyPet(Commerce* commerce)
    {
        if(commerce == NULL)
        {
            return;
        }
        for(Pet& pet:commerce->getPets())
        {
           if(id == pet.getId()&& lvl == pet.getLevel())
           {
               cout<<"你买了只"<<pet.getName()<<endl;
               break;
           }
        }
    }
};

int main()
{
    Commerce* commerce = new Commerce;
    Player p;
    p.buyPet(commerce);
    return 0;
}

从上面的代码可以看到,玩家Player不仅依赖了商会Commerce,还要频繁与Pet类打交道。当Pet发生变化时,Player也要跟着一起变化,然而我们的要求只是在藏宝阁购买到自己的召唤兽就行,不需要直接和召唤兽打交道,反而会把商会(中介)的功能弱化,从而导致玩家和召唤兽的耦合太高,因此我重新设计来结构如图:

这里写图片描述


重构的代码如下:
//
//  更好的可扩展性-迪米特原则.cpp
//  c++
//
//  Created by 刘龙玲 on 16/5/6.
//  Copyright © 2016年 liulongling. All rights reserved.
//

#include <iostream>
#include <string>
#include <set>
#include <list>

using namespace std;

static const string name[] = {"狂豹","律法","雷鸟人","大力金刚","吸血鬼"};

//召唤兽
class Pet
{
public:
    Pet()
    {

    }
    Pet(int id,int lvl,string name)
    {
        this->id = id;
        this->level = lvl;
        this->name = name;
    }
    int getId()
    {
        return this->id;
    }
    int getLevel()
    {
        return this-> level;
    }
    string getName()
    {
        return this->name;
    }
private:
    int id;
    int level;
    string name;
};


class AbstractGoods
{
public:
    virtual Pet sell(int id,int lvl) = 0;
};


//商会
class Commerce:public AbstractGoods
{
public:

    Commerce()
    {
        for(int i=0;i<10;i++)
      {
          Pet pet(1,i+5,name[i]);
          pets.push_back(pet);
      }
    }

    virtual Pet sell(int id,int lvl)
    {
        Pet p;
        for(Pet& pet:pets)
        {
            if(pet.getId() == id&&pet.getLevel())
            {
                return pet;
            }
        }

        return p;
    }
private:
    list<Pet> pets;
};

class Player
{
public:
    void buyPet(int id,int lvl)
    {
        AbstractGoods* good = new Commerce;
        Pet pet = good->sell(id,lvl);
        cout<<"你买了只"<<pet.getName()<<endl;
    }
};

int main()
{
    Player p;
    p.buyPet(1,2);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值