码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式六大原则(一):单一职责原则(SRP)

时间:2015-08-31 21:23:02      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:

定义:

        单一职责原则:就一个类而言,应该仅有一个引起它变化的原因。

 
原因:
        如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏。而如果想要避免这种现象的发生,就要尽可能的遵守单一职责原则。此原则的核心就是解耦和增强内聚性。
 
示例:
        如果我们不遵守单一职责原则,会产生怎样的后果?产生的后果,我们是否能够接受呢?
        我们去手机卖场的时候,往往可以发现,肯定在某个角落存在一个维修手机的地方,从这我们就可以看出这个卖场有两个职责(或者说是功能)。一个职责是负责卖手机,还有一个职责则是负责修理手机。那么我们就做一个假设:卖场出售A、B、C三种品牌的手机,同时也可以修理A、B、C三种品牌的手机。用一个类来表示这个过程:
#include <iostream>
#include <string>
#include <set>
using namespace std;
class PhoneStore
{
    set<string> PhoneBrand;
public:
    void AddPhoneBrand(string PhoneName);
    void SalePhoneBrand();
    void RepairPhoneBrand();
};
void PhoneStore::AddPhoneBrand(string PhoneName)
{
    PhoneBrand.insert(PhoneName);
}
void PhoneStore::SalePhoneBrand()
{
    set<string>::iterator set_it = PhoneBrand.cbegin();
    while (set_it != PhoneBrand.cend())
    {
        cout << "我们卖场有" << *set_it << "品牌的手机出售" << endl;
        set_it++;
    }
}
void PhoneStore::RepairPhoneBrand()
{
    set<string>::iterator set_it = PhoneBrand.cbegin();
    while (set_it != PhoneBrand.cend())
    {
        cout << "我们卖场能修理" << *set_it << "品牌手机" << endl;
        set_it++;
    }
}
int main()
{
    PhoneStore xmx;    //创建xmx手机卖场
    //添加手机卖场有售和能修理的手机品牌
    xmx.AddPhoneBrand("A");
    xmx.AddPhoneBrand("B");
    xmx.AddPhoneBrand("C");
    //手机卖场有售的手机品牌
    xmx.SalePhoneBrand();
    
    //手机卖场能修理的手机品牌
    xmx.RepairPhoneBrand();
    return 0;
}

输出:

我们卖场有A品牌的手机出售
我们卖场有B品牌的手机出售
我们卖场有C品牌的手机出售
我们卖场能修理A品牌手机
我们卖场能修理B品牌手机
我们卖场能修理C品牌手机

         好的,现在我们也有了手机卖场类,而且不仅能够卖A、B、C三种品牌的手机,还能修理A、B、C三种品牌的手机。那么,如果有一天,采购了新的一种D品牌手机,但是修理部门的人还没有学会如何修理D品牌的手机,那么如果我们再添加一个D品牌的手机,输出如下:

我们卖场有A品牌的手机出售
我们卖场有B品牌的手机出售
我们卖场有C品牌的手机出售
我们卖场有D品牌的手机出售
我们卖场能修理A品牌手机
我们卖场能修理B品牌手机
我们卖场能修理C品牌手机
我们卖场能修理D品牌手机

        但是,我们并不会修理D品牌的手机啊。糟糕了,这就是不遵循单一职责原则的后果,我原本只想修改出售手机的职责,没有想到的是修理手机的职责也发生了改变。所以说嘛(放个马后炮),就该遵循单一职责原则,要不然也不会出现这种坑问题,怎么办?改呗!修改后的类代码如下:

#include <iostream>
#include <string>
#include <set>
using namespace std;
class PhoneStoreSale
{
    set<string> PhoneBrand;
public:
    void AddPhoneBrand(string PhoneName);
    void SalePhoneBrand();
};
void PhoneStoreSale::AddPhoneBrand(string PhoneName)
{
    PhoneBrand.insert(PhoneName);
}
void PhoneStoreSale::SalePhoneBrand()
{
    set<string>::iterator set_it = PhoneBrand.cbegin();
    while (set_it != PhoneBrand.cend())
    {
        cout << "我们卖场有" << *set_it << "品牌的手机出售" << endl;
        set_it++;
    }
}
class PhoneStoreRepair
{
    set<string> PhoneBrand;
public:
    void AddPhoneBrand(string PhoneName);
    void RepairPhoneBrand();
};
void PhoneStoreRepair::AddPhoneBrand(string PhoneName)
{
    PhoneBrand.insert(PhoneName);
}
void PhoneStoreRepair::RepairPhoneBrand()
{
    set<string>::iterator set_it = PhoneBrand.cbegin();
    while (set_it != PhoneBrand.cend())
    {
        cout << "我们卖场能修理" << *set_it << "品牌手机" << endl;
        set_it++;
    }
}
int main()
{
    //出售手机部门
    PhoneStoreSale sale;    
    //添加出售手机的品牌
    sale.AddPhoneBrand("A");    
    sale.AddPhoneBrand("B");
    sale.AddPhoneBrand("C");
    sale.AddPhoneBrand("D");
    //手机销售有售的手机品牌
    sale.SalePhoneBrand();
    //修理手机的部门
    PhoneStoreRepair repair;
    //添加能修理手机的品牌
    repair.AddPhoneBrand("A");
    repair.AddPhoneBrand("B");
    repair.AddPhoneBrand("C");
    //手机修理部门能修理手机的品牌
    repair.RepairPhoneBrand();
    return 0;
}

输出:

我们卖场有A品牌的手机出售
我们卖场有B品牌的手机出售
我们卖场有C品牌的手机出售
我们卖场有D品牌的手机出售
我们卖场能修理A品牌手机
我们卖场能修理B品牌手机
我们卖场能修理C品牌手机
        咦,看到了吗?这就是我们想要的结果诶,所以说,还是要遵循单一职责原则,一个类,就应该只有一个原因引起它的变化,就像上面的PhoneStoreSale类,能够引起它改变得那只有Sale职责改变了,这个类就改变了。不要让一个类身兼多职,这样会造成很大的耦合度。
 
优点:
        1.提高了类的可读性,便于维护;
        2.降低了类的复杂度,一个类只负责一项职责;
        3.变更引起的风险降低了,变更是必不可少的,但它一个类就是一个职责,修改了一个类也就相当于修改了一个类,并不影响其他的类。
 
参考书籍:《大话设计模式》、《敏捷开发——敏捷软件开发》

 

 

 

设计模式六大原则(一):单一职责原则(SRP)

标签:

原文地址:http://www.cnblogs.com/fengxmx/p/4773888.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!