最通俗易懂--设计模式之七大原则

来源:互联网 发布:2016餐饮行业数据分析 编辑:程序博客网 时间:2024/04/28 23:01

我写的这一系列设计模式,可能会围绕Java+Android来举例,但是不影响阅读。

设计模式是什么?
设计模式是广大程序员长年累月的经验总结。这门课也不是太容易,我尽量理解,也尽量说的简洁并通俗易懂,共同学习。
设计模式有什么用?
优化你的代码,让代码可读性强,适用性高,软件体系更加灵活。
回看一下自己的代码有没有一种牵一发而动全身的害怕,稍微更改一点就要崩溃,设计模式就是来解决这些问题的。
设计模式重要吗?
如果现在还不了解他是干什么的,看看自己写的代码,看看开发文档的代码,要认真起来:我以后肯定要写到那样的代码体系。未优化代码+设计模式=开发文档代码格式。
学习设计模式要准备什么?
1我爱设计模式。
2.我爱设计模式。
3.我爱设计模式。


设计模式七大原则:
1. 单一职责原则/Single Responsibility Principle(自己只负责自己这一类的事)
2. 开闭原则/Open Close Principle(确定正确不轻易更改,在此基础扩展功能实现更改)
3. 里氏代换原则/Liskov Substitution Principle(父类可适用的地方子替换成子类可用且不报错)
4. 依赖倒置原则/Dependence Inversion Principle(针对抽象和接口编程,不依赖具体类)
5. 接口隔离原则/InterfaceSegregation Principles(把使用的接口拆分细化)
6. 迪米特原则/Law of Demeter(只与直接朋友联系)
7. 合成复用原则/Composite Reuse Principle(多使用合成/聚合方式,尽量不使用继承)


1. 单一职责原则/Single Responsibility Principle(自己只负责自己这一类的事)
我们看一些专业化的名词的时候,一般来说他的命名是他所描述内容的精华概括。单一职责原则的重点就是单一,举一个例子,我们需要设计一个类ImageLoader:他的功能主要是网络下载和本地缓存。一般我们怎么写?反正我肯定会这样做:把他们都放在一个类中,实现了所有的功能,也只有一个类,简洁方便。但是,单一职责的原则是这个类应该是一组相关性很高的方法或函数的集合。所以网络下载和本地缓存逻辑上应该为两个操作,故应设计两个类来分别实现。这就是单一职责原则。

2. 开闭原则/Open Close Principle(确定正确不轻易更改,在此基础扩展功能实现更改)
开闭原则讲究一开一闭,对扩展开放,对修改封闭。我们写代码最终目的是什么,是完成整个系统功能吗?不,这只是一个副产品,我们的主要目的应该设置为让整个系统稳定、灵活、适用性强。对于开闭原则,举一个例子:假如你写好了一个购物的代码类而且已经上线投入使用,现在按需求要在此代码类上加入购物车的功能,这样怎么做?或许你会选择修改那个以上线的代码,然后重新发布,但是考虑到修改的易出错性,而且你的功能设计正在投入使用,万一出错那将是要付出很大代价的。所以开闭原则的定义就是:对购物代码类进行扩展而不是修改它扩展可以实现原有的所有功能并加入自己的新方法或函数,所以这样做安全性大大提高,在你测试的时候就不必担心原来的代码会有大Bug(因为我们没有对他做修改)。

3. 里氏代换原则/Liskov Substitution Principle(父类可适用的地方子替换成子类可用且不报错)
这个命名是以原则提起人姓氏命名的,是一种纪念形式,不必过多追究。代换是这个原则的寓意所在,所有引用基类的地方都可以代换为他的子类。为什么父类可以代换为子类?里氏代换原则依赖于面向对象的继承和多态两大特性。我们写了父类class A其中有方法 void a(),如果再写一个类class B extends A那我们在类B中是不是要实现A的所有方法也就是void a(),所以我们在使用类A的地方完全可以用类B替换,而且不会报错,因为class B拥有class A的全部特性。

4. 依赖倒置原则/Dependence Inversion Principle(针对抽象和接口编程,不依赖具体类)
我们设计了一个图片缓存的类ImageCache,起始的设计实现是存储到手机内存,然后有需求需要存储到内存卡–>改ImageCache类,过几天又有需求要存储到外接硬盘–>改ImageCache类,计划跟不上变化….–>又改ImageCache类……这么做好累吧。。。而且一直在更改类,有没有违反了开闭原则。所以呢,针对抽象接口编程就要求我们设计一个ImageCache接口:

public interface ImageCache{    public Bitmap get(String url);    public void put(String url,Bitmap bmp);}

这样做,我们需要更改需求的时候呢,只需要更改Url存储地址这不就行了,不必麻烦去改代码了。

5. 接口隔离原则/InterfaceSegregation Principles(把使用的接口拆分细化)
按字面意思就是把接分割。客户端所依赖的接口不应该依赖他不需要的接口。
比如我们设计一个接口:

public interface mDownload{ public void ImageDownload(String url);//图片下载功能 public void imageCache(String url,Bitmap bmp);//图片缓存功能}

然后我们设计的Image类需要实现图片下载功能,不需要缓存,然而我们实现接口就必须实现两个方法:

public class Image implements mDownload{  public void ImageDownload(String url){//相关代码片}  public void ImageCache(String url,Bitmap bmp){}}

弊端其一是暴露了接口的结构,信息泄露。其二是须实现不需要的方法。
这还只是两个方法,如果接口方法过多,那岂不是大麻烦…..
所以接口隔离原则要求接口细化,这样设计:

//第一个接口public interface mDownload{public void ImageDownload(String url);}//第二个接口public interface mIMageCache{public void ImageCache(String url,Bitmap bmp);}

代码实现我们可以这样写:
需要下载功能的:

public class Image implements mDownload{ public void ImageDownload(String url){//相关代码片  }}

需要缓存功能的:

public class Image implements mImageCache{  public void ImageCache(String url,Bitmap bmp){//相关代码片  }}

需要下载和缓存功能的:

public class Image implements mDownload,MImageCache{  public void ImageDownload(String url){//相关代码片  }   public void ImageCache(String url,Bitmap bmp){//相关代码片  }}

6. 迪米特原则/Law of Demeter(只与直接朋友联系)
迪米特原则也称为最少知道原则,类与类之间可以比作我们生活中的的人与人。当你需要买一张火车票时,你下命令给同学去帮你买-_-!同学呢,或者坐公交去火车站,或者打的去火车站,或者网上帮你订购。。。然而你只要得到他给你反馈的结果,买到或没有或出了异常,而不关心他是怎么实现这件事情的(现实中肯定不是这样的),这就是最少知道原则,知道多了,也就是你知道他实现的方法,其一是信息泄露,其二是事情变复杂了,或许他实现了getHurt()方法,受伤了,你带他去医院。。。你本来只要实现help()让同学帮忙的方法,最后却实现了很多事,让你的类变得雍容复杂。所以这就是最少知道法则。

7. 合成复用原则/Composite Reuse Principle(多使用合成/聚合方式,尽量不使用继承)
合成是强烈的关联,聚合是部分关联。合成关系中部分与整体生命周期相同,唇亡齿寒。聚合中则不一定会一荣俱荣,一损俱损。重点是优先使用对象组合而不是继承。继承的局限性在于1.暴露全部结构信息。2.导入时是静态导入无法修改。例如:我们在网络条件下获取图片数据时需要联网,这个连接操作可以设计一个类:

public class Connect{  public void getConnect(String url){  //connect相关代码  }}

我们实现连接时:

public class ImageDownload extends Connect{  public void getConnect(String url){  //相关代码片  }}

如果现在我们产品升级了,需要继承其他类,这就无法实现了,然后根据合成复用这样改:

public class Connect{  public void getConnect(String url){  //connect相关代码  }}

继承其他类Other时同时保留网络连接的功能:

import com.position.Connect;//根据实际路径导入Connect类public class ImageDownload extends Other{  public void getOther(){  //Other类相关代码片  }  //网络连接功能这样实现  Connect net = new Connect();  net.getConnect(String url);}

这样做安全,方便,灵活多用。当然也并不是完全否定继承,组合和继承一起使用,提高工作效率。
什么时候用集成合适?在Android中当你需要自定义控件的时候,比如自定义Button这个时候继承Button在他的静态方法中覆写自己需要自定义的地方,这种场景需求方向和功能相对固定,而且继承后自己可以省出大量时间做自定义工作,而不用一个一个写需要实现的方法等。


好了,至此设计模式七大原则告一段落,我写的不是最官方,但确保通俗易懂,有错就改,共同勉励,加油!接下来23种设计模式,一个一个来。

4 0
原创粉丝点击