关于单一职责原则的一点理解

前端之家收集整理的这篇文章主要介绍了关于单一职责原则的一点理解前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

写这篇博文,是因为在论坛里看到了一篇有关这一话题的帖子,产生了一些想法,自知记忆力较差,便急切的想找到个地方记录下来,以便日后温故。

我所说的帖子的地址是http://topic.csdn.net/u/20110120/12/4ee6335d-247d-4c1f-8c9d-8d70f44ddaba.html

提问者提出了这样的问题:

Shape是抽象基类,Triangle和Rectangle继承自Shape,Draw()、SaveToXml()、LoadFromXml()是三个虚函数
按照SRP(单一职责原则),把这三个虚函数放在一个类中,是否不好?应该怎么做?分别创建三个子类去实现?

class Shape{
public:
virtual Draw()=0;
virtual SaveToXml()=0;
virtual LoadFromXml()=0;
};

class Triangle public: Shape{
...
};

class Rectangle public: Shape{
...
};


个人认为8楼的解答最给力:

class Shape{
public:
virtual Draw()=0;

};

class XmlPersist
{public:
virtual SaveToXml()=0;
virtual LoadFromXml()=0;
};

class Triangle public: Shape,public XmlPersist{
...
};

class Rectangle public: Shape,public XmlPersist {
...
};


现在,说说我对这个问题的理解。

人们通常认为,之所以要坚持这样的一个原则,目的是要一个类只做一件事情。可是怎么样的事情才算是一件事情呢?考试算是一件事情么?如果算,那么考试中还包含了复习,准备考试用具,答题,交卷子等一系列的事情,这样想来考试算是一件事情么?

更深奥的解释是,让一个类只有一个可以引起它变化的原因。这样的解释就更让人难以理解了,软件概念如此复杂,如此多变,所谓的这一个引起变化的原因到底是指一种情况,还是一个因素亦或是一个条件?

为什么一个类的职责不宜过多?有人会说那样在使用或修改时会遇到麻烦,可是为什么一个类的职责过多时就会导致修改或使用时遇到麻烦呢?这里的职责又是什么概念?一个函数代表一个职责么?还是一个类代表一个职责?还是一个模块代表一个职责?

我想起《人月神话》中的一句话,开发软件的主要根本任务是打造抽象软件实体的复杂概念结构。我这样理解这句话:人,通过一系列手段和方法将现实生活中的事物映射成复杂的软件概念,在这个映射的过程中,我们采取各种各样的设计模式,各种原则,无非是想使映射后的软件概念最大限度的反应真实的事物。

我之所以人为8楼的答案最给力,并不是因为他的方法符合了职责单一性原则,而是在于我人为他的方法最大程度的反应了真实的事物(事实上我现在仍不理解单一职责)。

问一问自己,什么是Shape?当你只考虑什么是Shape的时候,你会考虑到读取文件么?当你只考虑打开一个XML文件,写一个XML文件时,你会考虑到Shape么?Shape本身和XML文件,这两者之间本身没有任何关系。从根本上讲,他们完全是两个不同的问题域里的东西。你也许会说,他们之间终究是有联系的呀,错,他们之间没有任何联系,你所说的联系是软件概念中的联系,我所说的没有联系,是现实世界中的联系。可如果我们让他们在软件概念中仍和现实世界中一样,没有任何联系,那么似乎这段程序,或者说功能就没有办法实现了。

为了实现其功能,我们只好让Triangle继承两个完全没有联系的类,如此一来,我们所期望的软件概念中的联系被Triangle实现,而两个基类则最大程度的反映了现实事物间的关系。如此,两个基类都做了自己该做的事情,而且是一件事情。但是新的问题出现了,似乎Triangle做了两件事情,一件是Draw(),一件是把自己保存到XML文件中和从XML文件获取自己。

那么这又该如何应对呢?以笔者之愚见,Draw()这个方法根本不是Shape及其子类该做的事情,如果是我设计这段代码,我更倾向于将这三个方法放到一个抽象类(Operate)里,这个类专门负责对图形的操作,这样,Shape类及其子类最大程度上反应了现实世界中的事物,而我所说的Operate虽然在现实世界中找不到一个与之对应的具体实物,但它可以找到一个与之对应的抽象概念------操作图形。

对于这个问题,我的思考还很混乱,也希望博友们能给些意见,更欢迎大家批评指正。

原文链接:https://www.f2er.com/javaschema/287025.html

猜你在找的设计模式相关文章