PS:本人边学边记录,所以可能有欠缺有错误有不足之处,还望指导!
在学习设计模式之前我们有必要先了解一下一些设计原则.
其实设计原则也是从设计模式里来的,所以暂时不需要太理解,毕竟光看原则可能有时候理解不了.
SOLID设计原则
讲设计原则,则不得不先提一下SOLID设计原则.
它的每个字母分别代表一个原则,接下来分别介绍一下.
单一职责原则(SRP)
单一职责原则(Single Responsibility Principle,SRP)
a class should have only a single responsibility (i.e. only one potential change in the software's specification should be able to affect the specification of the class)
简单来说就是:一个类应该只有一个职责(只有一个潜在的改变能影响这个类);
每一个引起类变化的原因就是一个职责,当类具有多职责时,应该把多余职责分离出去,分别创建类来完成,
否则这个类的耦合度会不断提升,不利于维护等.
比如某些所谓的多功能道具,集多少多少功能于一体,吹得很牛逼,结果呢?其中一个坏了,整个都坏了,全完蛋.
如果说我们的代码也这样,一个类又有Http请求又有IO操作的方法又封装了各种Util方法,背负各种职责,耦合度高得能吓死你,还怎么快乐地敲代码?
SRP的优点很明显:高内聚,低耦合,类结构逻辑清晰明了,提高了可读性,同时也易于维护
开闭原则(OCP)
开闭原则(Open Closed Principle)
“software entities(classes, modules, functions, etc.) should be open for extension, but closed for modification.”
实体(类,模块..等)应该对扩展开放,对修改关闭.
也就是说实体可以做到不修改源代码就可以实现功能扩展.
比如我们实现了功能A,测试完后发布.后来我们需要增加功能,在不得已的情况下我们最好是对原有的代码功能实现扩展,而不是去修改原来的代码.
因为原来的代码经过了测试,而我们再次去修改很有可能破坏原来的代码,或者带来Bug,所以我们需要对修改关闭.
做到开闭原则可以做到稳定,可扩展
But,臣妾表示做不到啊!
里氏代换原则(L)
里氏代换原则(Liskov Substitution Principle,LSP)
It states that, in a computer program, if S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e., objects of type S may substitute objects of type T) without altering any of the desirable properties of that program (correctness, task performed, etc.).
简单来说就是:父类可以出现的地方,子类也可以出现,父类都可以被子类代替而无需改动.
其实这原则就是运用了继承,多态的特性,在很多设计模式中都有体现.
其实这个原则要求我们做的也很好理解,这么做就可以用一个方法符合所有T的类型,节省代码.
接口隔离原则(ISP)
接口隔离原原则(Interface Segregation Principle,ISP)
(ISP) states that no client should be forced to depend on methods it does not use.
客户端不应该被强迫地依赖那些根本用不上的方法.
什么意思?
假设有个接口A,A有三个方法,而我们的类B需要其中的某一个,如果让B实现A那么B就会多依赖两个用不上的方法,这就违背了该原则.
另外这么做还有另外一个非常大的隐患,如果我们改变了A的其他两个方法,那么会影响到B.
在Java源码中我们可以找到很多接口都只有一个方法,比如:
public interface AutoCloseable {
void close() throws Exception;
}
public interface Comparable {
int compareTo(T another);
}
其实原因就在这个接口隔离原则上.
ISP is intended to keep a system decoupled and thus easier to refactor, change, and redeploy.
接口隔离原则优点:
- 让我们的程序解耦,更容易重构,改变,重新部署.
另外个人觉得接口隔离原则跟SRP其实挺类似,它也可以提高内聚,降低耦合,提升可读性~
依赖倒置原则(DIP)
依赖倒置原则(Dependency Inversion Principle)
the dependency inversion principle refers to a specific form of decoupling software modules. When following this principle, the conventional dependency relationships established from high-level, policy-setting modules to low-level, dependency modules are inverted (i.e. reversed), thus rendering high-level modules independent of the low-level module implementation details.
简单说就是:高级模块独立于低级模块的实现细节.
DIP指明了:
- 高级模块不应该依赖低级模块,它们都应该依赖于抽象.
- 抽象不应该依赖细节.细节应该依赖于抽象.
其他必须知道的原则
DRY
Don't repeat yourself.
不要重复自己,也许你听过很多次,但它绝不是复制黏贴那么简单.
优先使用组合,少用继承
在EffectiveJava 和HeadFirstDesignPattern里不止一次看到优先使用组合的建议.
继承的缺点可不少.
针对接口编程,而不是实现
这里的接口指interface
和抽象
.
封装变化
把经常变化的代码封装起来,与不变的代码隔离开.
迪米特法则
迪米特法则 (Law of Demeter Principle),也称为“最少知识原则(Principle of Least Knowledge)
wiki百科的解释挺好的,我就照搬过来了,如下:
- 每个单元对于其他的单元只能拥有有限的知识:只是与当前单元紧密联系的单元;
- 每个单元只能和它的朋友交谈:不能和陌生单元交谈;
- 只和自己直接的朋友交谈。
很多面向对象程序设计语言用"."表示对象的域的解析算符,因此得墨忒耳定律可以简单地陈述为“只使用一个.算符”。 因此,a.b.Method()违反了此定律,而a.Method()不违反此定律。
一个简单例子是,人可以命令一条狗行走(walk),但是不应该直接指挥狗的腿行走,应该由狗去指挥控制它的腿如何行走。
- 优点
使得软件更好的可维护性与适应性。
因为对象较少依赖其它对象的内部结构,可以改变对象容器(container)而不用改变它的调用者(caller)。
总结
如果我们的目标是:Reliable,Scalable,Maintainable.
,那么设计原则可以帮助我们实现,学习理解设计原则对编码大有裨益!~
理论需要与实际结合,多在写代码的时候考虑一下,对提高代码质量有很大的帮助~
好了,这次就写那么一点点,如有错误,欢迎批评指正,也欢迎交流!
推荐书籍
HeadFirstDesignPattern.
Effective Java.
参考/更多
http://colobu.com/2015/03/05/10-object-oriented-design-principles-you-should-know/
编程经验之接口分离原则
设计模式之面向对象与类基础特征概念
另外欢迎关注:
我的Github
我的微博
我的微信公众号: