笔者刚接触设计原则的时候,觉得一头雾水,不知道他有什么用。在经历了一段时间的代码加上了解Java设计模式之后。笔者忽然觉得自己以前写的代码就是一堆*。所以,笔者认为设计原则和设计模式对于软件编程设计(非码农)来说是至关重要的事情。相信很多学习编程的人,和我有同样的感受。
我对设计模式和设计原则的理解是:如果把程序员比作武侠,那么设计模式就是修炼内功的易筋经,设计原则就是修炼内功的心法总纲,而具体的技术实现(代码编写)就是罗汉拳。如果你只想自保,那么会罗汉拳就可以了(能够用代码实现功能),不过如果你想要成为武林高手,那么你必须要修炼内功(设计模式和设计原则)。而现在,我仅谈下我对Java六大设计原则(单一职责原则,里氏替换原则,依赖倒置原则,接口隔离原则,迪米特法则和开闭原则)的理解。(初学者,高手轻喷)
1.单一职责原则
按照我自己的习惯。我喜欢通过字面的意思来解析重要重要词汇的意义。“单一职责”四个字,“单一”很简单,就是“仅仅一个”的意思。重要的是“职责”。“职责”的意思就是:“某个人或者是事务具有要做或者是承担某类动作活着是行为的义务活着责任”,用在Java里面,简单来说这里的“职责”部分等价于“方法”。单一职责原则就是:在Java中,一个类仅仅实现一个职责。
那么单一职责有什么用呢?
我的理解是:单一职责原则就是为了便于后期代码的维护,增强程序的健壮性而要求我们在某些场景下的程序设计阶段要准守的关于Java方法和类关系结构的一种设计原则。这样也许抽象和难懂,简单的理解就是单一设计模式是教我们怎么处理类和方法之间的关系的一种行为原则。
比如:
/**
* 类 -- 人
* @author BeiChengLuo
*
*/
public class Person {
// 职责 -- 吃饭
public void eat(){
System.out.println("人主要吃饭");
}
}
/**
* 客户端
* @author BeiChengLuo
*
*/
public class MainClass {
public static void main(String[] args) {
Person person = new Person();
person.eat();
}
}
输出:
解读:
以上的例子中,是最简单的不完善的单一设计模式(一个类(Person类)只负责一项职责(eat()方法))。但是可是并不是所有的人主食都是饭,南方人主要吃饭,北方人则主要吃馒头。这个时候,职责eat()就分化成为了粒度更细的职责:北方人主要吃馒头,南方人主要吃饭。这种因为某种原因,职责P被分化为粒度更细的职责P1和P2的情况称为职责扩散。
处理职责扩散的设计原则有:
(1).一个抽象(或)类多个子类,一个方法(标准单一职责原则)
(2).一个类,多个方法(满足方法单一职责原则)
(3).一个类,一个方法(满足类和方法的单一设计原则但是代码不满足单一职责原则)
(1).一个抽象类多个子类,一个方法(标准单一职责原则)
/**
* 抽象类
* @author BeiChengLuo
*
*/
public interface Person {
// 职责
void eat();
}
/**
* 类 -- 北方人
*/
public class NorthPerson implements Person {
// 职责 -- 北方人主要吃面
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println("北方人主要吃面");
}
}
/**
* 类 -- 南方人
* @author BeiChengLuo
*
*/
public class SouthPerson implements Person {
// 职责 -- 南方人主要吃饭
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println("南方人主要吃饭");
}
}
public class MainClass {
public static void main(String[] args) {
Person northPerson = new NorthPerson();
northPerson.eat();
Person southPerson = new SouthPerson();
southPerson.eat();
}
}
输出:
(2).一个类,多个方法(满足方法单一职责原则)
/**
* 类 -- 有两个方法,不满足单一职责原则
* @author BeiChengLuo
*
*/
public class Person {
// 职责 -- 吃饭
public void eat(){
System.out.println("人主要吃饭");
}
// 职责 -- 北方人主要吃面
public void eatNorth(){
System.out.println("北方人主要吃面");
}
}
/**
客户端
*/
public class MainClass {
public static void main(String[] args) {
Person northPerson = new Person();
northPerson.eatNorth();
Person southPerson = new Person();
southPerson.eatSouth();
}
}
输出同上
(3).一个类,一个方法(满足类和方法的单一设计原则但是代码不满足单一职责原则)
/**
* 类 -- 有两个方法,不满足单一职责原则
* @author BeiChengLuo
*
*/
public class Person {
// 职责
public void eat(String typePerson){
// 北方人职责
if (typePerson.equals("north")) {
System.out.println("北方人主要吃面");
// 南方人职责
}else {
System.out.println("南方人主要吃饭");
}
}
}
/**
* 客户端
* @author BeiChengLuo
*
*/
public class MainClass {
public static void main(String[] args) {
Person northPerson = new Person();
northPerson.eat("north");
Person southPerson = new Person();
southPerson.eat("");
}
}
输出结果同上。
上面的例子中,出现了职责扩散的情况,那么如果使用(1)代码很简洁,如果要增加“外国人”,增加一个实现Person接口的类既可,如果“北方人”出现“东北人”和“北京人”实现不同的“职责”,我们让他们继承“北方人”,并且重载“职责”相关的方法(eat()方法既可)。
使用(2)不用修改原来的方法,增加一个北方人方法就好。而使用(3)则全部修改了以前的方法,这样,如果这个方面是复杂的,那么在后期代码中,将会非常容易出现错误,并且随着代码复杂度的提升修改其错误的难度将会加倍困难。
以上三种比较:
(1).标准单一职责原则 -- 阅读性(维护)最好,代码量最大,使用最复杂
(2).方法单一职责原则 -- 阅读性(维护)中等,代码量最小,使用中等
(3).标准和方法单一职责模式 -- 阅读性(维护)最差,代码量中等,使用最简单
综上所述,通常使用第一种。
原文地址:http://11123082.blog.51cto.com/11113082/1737875