单一职责
定义
不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责。
问题由来
类T负责两个不同的职责:职责P1,职责P2。当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障。
解决方案
遵循单一职责原则。分别建立两个类T1、T2,使T1完成职责P1功能,T2完成职责P2功能。这样,当修改类T1时,不会使职责P2发生故障风险;同理,当修改T2时,也不会使职责P1发生故障风险。
优点
可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多;
提高类的可读性,提高系统的可维护性;
变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响。
需要说明的一点是单一职责原则不只是面向对象编程思想所特有的,只要是模块化的程序设,都适用单一职责原则,比如方法,接口都是,一个方法应该只做一件事,一个接口应该只有一类行为。
违反单一职责的坏处
如果一个类承担的职责过多,等于把这些职责耦合在了一起;一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏。
举例:
下面类违反了单一职责
public class MyImageView {
private String mPath;
public void setPath(String path) {
//违反单一指责,一个方法一件事
mPath = path;
prepare();
}
private void prepare() {
//一系列初始化操作
}
public void showImg(){
if(isFileExisted()){
Bitmap bitmap = loadImg();
draw(bitmap);
}
}
private void draw(Bitmap bitmap) {
//show img
}
//违反单一职责,应该归类到第三方公共方法中
private Bitmap loadImg() {
return BitmapFactory.decodeFile(mPath);
}
//违反单一职责,应该归类到第三方公共方法中
private boolean isFileExisted() {
if(mPath == null || mPath == ""){
return false;
}
File file = new File(mPath);
if(file.exists() && file.isFile()){
return true;
}
return false;
}
}
首先MyImageView应该只有涉及展示的UI操作,isFileExisted()、loadImg()这类方法属于第三方的公共方法,不应该放在MyImageView中,其次在setPath()中,不仅仅做了mPath的赋值操作,还做了prepare操作,这里也是违反了单一职责(一个方法一件事)
矫正方案
文件工具类
public class FileUtils {
public static boolean isFileExisted(String path) {
if(path == null || path == ""){
return false;
}
File file = new File(path);
if(file.exists() && file.isFile()){
return true;
}
return false;
}
}
图片加载类
public class BitmapHelper {
static final BitmapHelper sHelper = new BitmapHelper();
private BitmapHelper(){}
public static BitmapHelper getInstance() {
return sHelper;
}
public Bitmap loadImg(String path) {
return BitmapFactory.decodeFile(path);
}
}
图片展示view
public class MyImageView {
private String mPath;
public MyImageView(){
prepare();
}
public void setPath(String path) {
mPath = path;
}
private void prepare() {
//一系列初始化操作
}
public void showImg(){
if(FileUtils.isFileExisted(mPath)){
Bitmap bitmap = BitmapHelper.getInstance().loadImg(mPath);
draw(bitmap);
}
}
private void draw(Bitmap bitmap) {
//show img
}
}
总结
单一职责原则:一个类应该仅有一个引起它变化的原因。即:
管理复杂度,找出容易变化/改变的区域,隔离变化。
单一职责原则是最简单的原则之一,也是最难正确运用的原则之一,因为我们很容易把职责结合一起。
软件设计很重要的工作就是发现职责并把那些职责相互分离,我们平时或多或少的都使用到单一职责原则,如果开发中能关注到就更好了。