1
单一职责原则
一开始我需要一只会吃吃喝喝的宠物,于是我写了
public class Animal {
public void eat() {
Log.i("", "eat");
}
public void drink() {
Log.i("", "drink");
}
}
一个领养的方法
public class Host {
public void adopt(Dog dog){
Log.i("", "i get dog");
}
}
然后我发现要区分下狗和猫的吃喝,我改
public class Animal {
public void eat(String kind) {
if (kind.equals("cat")) Log.i("", "吃鱼");
if (kind.equals("dog")) Log.i("", "吃骨头");
}
public void drink(String kind) {
if (kind.equals("cat")) Log.i("", "喝鱼汤");
if (kind.equals("dog")) Log.i("", "喝骨头汤");
}
}
最后我发现鸡,鸭,鹅。。。都要加进来,我要写多少if,狗带boy。。。我不如把每种动物各自建个类,各自负责自己的吃喝,来一个加一个岂不是happy。于是默默记住
单一职责原则:不要存在多于一个导致类变更的原因
2
里氏替换原则(直扩不改原则)
于是我新建了一个类Dog继承了开始的时候的Animal,至于为什么要继承。。。来源于直觉。。。animal>dog。。。包含关系不是吗?
public class Dog extends Animal{
public void eat() {
Log.i("", "吃骨头");
}
public void drink() {
Log.i("", "喝骨头汤");
}
}
写完了以后发现有点不对劲,貌似违反了
里氏替换原则:子类可以扩展父类的功能,但不能改变父类原有的功能。
我这样一写如果把用到Animal的地方换成Dog,所有的动物都变成吃骨头了。
3
依赖倒置原则
既然继承不能用了,领养的方法出现了难题,我总不能
public void adopt(Dog dog){
Log.i("", "i get dog");
}
public void adopt(Cat cat){
Log.i("", "i get cat");
}
.....无数鸡,鸭,鹅方法飞过......
要是真这样估计累死。于是,我想到了接口
public interface Animal {
public void eat();
public void drink();
}
public class Dog implements Animal{
public void eat() {
Log.i("", "吃骨头");
}
public void drink() {
Log.i("", "喝骨头汤");
}
}
完美。契合了面向接口编程,而且符合
具体内容:面向接口编程,依赖于抽象而不依赖于具体。写代码时用到具体类时,不与具体类交互,而与具体类的上层接口交互。
4
接口隔离原则
然后发现猫有爬树的技能,狗有汪汪的神级,于是我加了
public interface Animal {
public void eat();
public void drink();
//猫爬树
public void climbTree();
//狗汪汪
public void yell();
}
于是狗变成
public class Dog implements Animal{
public void eat() {
Log.i("", "吃骨头");
}
public void drink() {
Log.i("", "喝骨头汤");
}
@Override
public void climbTree() {
}
@Override
public void yell() {
Log.i("", "汪汪");
}
}
由于狗不会爬树,所以爬树的方法空着。转而一想这样不行,狗还不会飞,不会。。。。等引入其他大量动物,岂不是有大量的空方法?
接口隔离原则:客户端不应该被强迫地依赖那些根本用不上的方法。
我只好把接口拆开,用组合搞定,组合是比较推荐的方式。
public interface Animal {
public void eat();
public void drink();
}
public interface Yell {
//狗汪汪
public void yell();
}
public class Dog implements Animal, Yell{
public void eat() {
Log.i("", "吃骨头");
}
public void drink() {
Log.i("", "喝骨头汤");
}
@Override
public void yell() {
Log.i("", "汪汪");
}
}
这个原则的意思是:每个接口中不存在子类用不到却必须实现的方法,如果不然,就要将接口拆分。使用多个隔离的接口,比使用单个接口(多个接口方法集合到一个的接口)要好。
5
最少知道原则
就是说:一个类对自己依赖的类知道的越少越好。也就是说无论被依赖的类多么复杂,都应该将逻辑封装在方法的内部,通过public方法提供给外部。这样当被依赖的类变化时,才能最小的影响该类。
最少知道原则的另一个表达方式是:只与直接的朋友通信。类之间只要有耦合关系,就叫朋友关系。耦合分为依赖、关联、聚合、组合等。我们称出现为成员变量、方法参数、方法返回值中的类为直接朋友。局部变量、临时变量则不是直接的朋友。我们要求陌生的类不要作为局部变量出现在类中。
6
开闭原则
直接抛出定义吧
开闭原则:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭
感觉这个原则容易看懂,最难做到。白话就是不要改你以前写的代码,你应该加一些代码去扩展原来的功能,来实现新的需求。好处很好理解,改原来的代码很容易影响原来的功能,特别是接手别人的代码,不理解原先业务场景的情况下。关于‘不要动之前的代码’感觉槽点无数啊,看自己写的代码想吐有木有?别人的代码简直...?之前哪里会想到会有这种鬼需求?.......
分类
范围 | 创建型 | 结构型 | 行为型 |
类 | Factory Method(工厂方法) | Adapter(类) (适配器) | Interpreter(解释器) Template Method(模版方法) |
对象 | Abstract Factory(抽象工厂) Builder(建造者) Prototype(原型) Singleton(单例) | Adapter(对象)(适配器) Bridge(桥接) Composite(组合) Decorator(装饰者) Façade(外观) Flyweight(享元) Proxy(代理) | Chain of Responsibility(职责链) Command(命令) Iterator(迭代器) Mediator(中介者) Memento(备忘录) Observer(观察者) State(状体) Strategy(策略) Visitor(访问者) |
再细点分类:
范围 | 创建型 | 结构型 | 行为型 |
对象创建 | Singleton(单例) Prototype(原型) Factory Method(工厂方法) Abstract Factory(抽象工厂) Builder(建造者) |
|
|
接口适配 |
| Adapter(适配器) Bridge(桥接) Façade(外观) |
|
对象去耦 |
|
| Mediator(中介者) Observer(观察者) |
抽象集合 |
| Composite(组合) | Iterator(迭代器) |
行为扩展 |
| Decorator(装饰)
| Visitor(访问者) Chain of Responsibility(职责链) |
算法封装 |
|
| Template Method(模板方法) Strategy(策略) Command
|
性能与对象访问 |
| Flyweight(享元) Proxy(代理) |
|
对象状态 |
|
| Memento(备忘录) State(状态) |
其它 |
|
| Interpreter(解释器) |
|
|
|
|