转载请标明: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;
}