【前言】
最近在学习设计模式,设计模式是面向对象编程的。设计模式有6大原则,而实际上都是互补的,也就是说一些原则需要利用另一些原则来实现自己。下面来简单的介绍一下六大原则其中之二
【单一职责原则】
1、单一职责原则的由来
初学者在编程的时候可能一开始会有这样的经历,使用一个类来实现很多的功能,新添加的甚至不相关的功能都放在一个类中来实现,煮成了一锅大杂烩,往往使得某个类包罗万象,无所不能。可能刚开始实现的功能比较简单,这样做不会引起很大的问题。但是随着之后项目复杂度的提升,各种不相关的代码耦合在一起,一旦有功能的更改或增删,修改的代码很可能导致其他功能不能正常运行,也就是违背了单一职责原则
2、什么是单一职责原则
不要存在多于一个导致类变更的原因。通俗的说,就是一个类只负责一项职责
在软件设计中,秉承着“高内聚,低耦合”的思想,让一个类仅负责一项职责,如果一个类有多于一项的职责,那么就代表这个类耦合性变高了,这些职责耦合在了一起,这是比较脆弱的设计。因为一旦某一项职责发生了改变,需要去更改代码,那么有可能会引起其他职责改变。所谓牵一发而动全身,这显然是我们所不愿意看到的,所以我们会把这个类分拆开来,由两个类来分别维护这两个职责,这样当一个职责发生改变,需要修改时,不会影响到另一个职责。
单一职责原则不只是面向对象编程思想所特有的,只要是模块化的程序设计,都适用单一职责原则。
3、为什么要用单一职责原则
说到单一职责原则,很多人都不屑一顾,因为它太简单了,这是常识。在编程中,谁也不希望因为修改了一个功能导致其他的功能发生故障。而避免出现这一问题的解决方法就是遵循单一职责模式。虽然单一模式如此简单,但是也会有违背这一原则的代码存在。为什么会出现这种现象?因为有职责扩散,就是因为某种原因,职责P被分化为粒度更细的职责P1和P2
举例说明,用一个类描述动物呼吸这个场景,代码如下:
class Animal
{
public void breathe(String animal)
{
System.out.println(animal + "呼吸空气");
}
}
public class Client
{
public static void main(String[] args)
{
Animal animal=new Animal();
animal.breathe("牛");
animal.breathe("羊");
animal.breathe("猪");
}
}
class Animal
{
public void breathe(String animal)
{
if("鱼".equals(animal))
{
System.out.println("呼吸水");
}
else
{
System.out.println("呼吸空气");
}
}
}
public class Client
{
public static void main(String[] args)
{
Animal animal = new Animal();
animal.breathe("牛");
animal.breathe("羊");
animal.breathe("猪");
animal.breathe("鱼");
}
}
4、遵循单一职责原则的优点
(1)降低了类的复杂度。一个类只负责一项职责比负责多项职责要简单得多
(2)提高了代码的可读性。一个类简单了,可读性自然就提高了
(3)提高了系统的可维护性。代码的可读性高了,并且修改一项职责对其他职责影响降低了,可维护性自然就提高了
(4)变更引起的风险变低了。单一职责最大的优点就是修改一个功能,对其他功能的影响显著降低
【开放-封闭原则】
1、什么是开放封闭原则
开放封闭原则是所有面向对象原则的核心。
所谓开放封闭原则,软件实体(类、模块、函数等等)应该是可扩展,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的
开放封闭原则主要体现在两个方面:
(1)对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况
(2)对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要求对类进行任何修改
2、为什么要用开放-封闭原则
对于程序设计而言,如何设计才能面对需求的改变却可以保持相对的稳定,从而可以使得系统可以在第一个版本的基础上不断的推出新的版本呢?答案是在程序设计的时候使用开放封闭原则。但是在设计的时候,绝对对修改的关闭是不可能的,无论模块是多么的封闭,都存在一些无法对之封闭的变化,既然不可以完全的封闭,设计人员必须对他设计的模块应该对哪种变换的封闭做出选择,他必须猜测出最有可能发生变换的种类,然后构造抽象来隔离那些变化
在我们最初写代码的时候,假设变化不会发生,当变化发生时我们就构造抽象类来隔离变化。当然,不是在什么情况下应对变化都是容易的
开放封闭原则是面向对象的核心所在,遵循这个原则可以带来面向对象所谓的巨大的好处,也就是可维护、可扩展、可复用、灵活性好。然而,对于应用程序中的每个部分都刻意的抽象同样不是一个好主意,拒绝成熟的抽象和抽象一样重要
3、如何使用开放封闭原则?
实现开放封闭的核心思想就是对抽象编程,而不对具体编程,因为抽象相对稳定。让类依赖于固定的抽象,所以对修改就是封闭的,而通过面向对象的继承和多态机制,可以实现对抽象体的继承,通过覆写其方法来改变故友行为,实现新的扩展方法,所以对于扩展就是开放的
对于违反这一原则的类,必须通过重构来进行改善。常用于实现的设计模式主要有Template Method模式和Strategy模式。而封装变化,是实现这一原则的重要手段,将经常变化的状态封装为一个类
以银行业务员为例:
没有实现开放封闭原则设计的:
public class BankProcess
{
public void Deposite(){} //存款
public void Withdraw(){} //取款
public void Transfer(){} //转账
}
public class BankStaff
{
private BankProcess bankpro = new BankProcess();
public void BankHandle(Client client)
{
switch (client .Type)
{
case "deposite": //存款
bankpro.Deposite();
break;
case "withdraw": //取款
bankpro.Withdraw();
break;
case "transfer": //转账
bankpro.Transfer();
break;
}
}
}
//首先声明一个业务处理接口
本文只是对基础知识做一个小小的总结,不深究。如有不同,见解欢迎指正
本文所有代码均已通过作者测试
本文所有内容均为作者原创,如有转载,请注明出处