设计模式六大原则(1):单一职责原则

来自手机的一个java学习宝典的APP,代码和解释都是自己手打后实践了下!

package study.test.legon;

import java.util.Scanner;

public class AcountYear {

/**
* 设计模式的六大原则,单一职责原则
* 题目:输入某年某月某日,判断这一天是这一年的第几天
*/
public static void main(String[] args) {
int year, month,day;
int days = 0;
int e = 0;
int d = 0;

do{
System.out.println("输入某年");
year = printNum();
System.out.println("输入某月");
month = printNum();
System.out.println("输入某天");
day = printNum();

//判断时间的输入正确与否
if(year<0||month<0||day<0||month>12||day>31){
System.out.println("时间输入错误,请重新输入");
e = 1;
}
//判断2月份的时间是否输入错误,闰年29,平年28
/**
* 闰年:①、普通年能被4整除且不能被100整除的为闰年。
* ②、世纪年能被400整除的是闰年
*/
//这是闰年,那么2月只有29天
if(year%400==0||(year%4==0&&year%100!=0)){
if(month==2&&day>29){
System.out.println("2月份的时间输入错误");
e = 1;
}
}else{
if(month ==2&&day>28){
System.out.println("2月份的时间输入错误");
e = 1;
}
}
}while(e==1);

//计算是这一年的第几天
for(int i=0;i<month;i++){
switch (i) {
/**
* 判断月份30和31天的诀窍,我记得老妈教过我,7前单月大,7后单月小,所以1,3,5,7,8,10,12这几月是31天
* 然后4,6,9,11这几月是30天
* 2月依据闰年,平年来判断
*/
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
days = 31;
break;
case 4:
case 6:
case 9:
case 11:
days = 30;
break;
case 2:
if((year%400==0)||(year%4==0&&year%100!=0)){
days = 29;
}else{
days = 28;
}
break;
}
d = d + days;
}
System.out.println(year+"-"+month+"-"+day+"是这一年的第"+(d+day)+"天");
}

public static int printNum(){
int num ;
Scanner scanner = new Scanner(System.in);
num = scanner.nextInt();
return num;
}
}

/**
* 定 义:不能存在多余一个导致类变更的原因,通俗的说,即一个类只负责一项职责.
* 问题由来:类T负责两个不同的职责:职责P1,职责P2.当由于职责P1需求发生改变而修改T的时,
* 有可能造成原本运行正常的职责P2发生故障
* 解决方案:遵循单一职责原则.分别建立两个类T1,T2来完成职责P1,P2!这样在修改T1时不会影响到P2
*
* 单一原则比较简单,所以很多人不屑一顾,但是经验丰富的程序员也会有时候违背这一原则,因为有时候职责扩散
* 就好比原本一个职责P被细分化成了P1和P2
* 比如:类T只负责职责P,这样设计符合单一职责原则,后来由于某种原因,可能程序员境界提高,可能需求改变,需要把
* P分化成P1和P2了,那么按照单一职责原则,需要创建一个T1和T2.但是程序写好的情况下这么做太浪费时间,.所以
* 简单的修改T,用它来负责两个职责是个比较不错的选择,虽然这样做有背于单一职责原则.
* 这样做的风选在于职责的扩散不稳定,因为我们没有想到职责P在未来可能会扩展到P1,P2.....Pn,所以记住,在职责
* 扩散到我们无法控制的程度之前,立刻对代码进行重构
*
* 举例说明:
* 用一个类来描述动物呼吸的场景
*/
class Animal{
public void breathe(String animal){
System.out.println(animal+"呼吸空气");
}
}
class client{
public static void main(String[] args){
Animal animal = new Animal();
animal.breathe("牛");
animal.breathe("羊");
animal.breathe("猪");
}
}

/**
* 结果可想而知,牛/羊/猪呼吸空气
* 程序上线后,发现问题了,并不是所有的动物都呼吸空气,比如鱼呼吸水.
* 修改时遵循单一职责原则,需要将Animal细分为陆生生物Terrestrial和水生生物Aquatic
*/
class Terrestrial{
public void breathe(String animal){
System.out.println(animal+"呼吸空气");
}
}
class Aquatic{
public void beathe(String animal){
System.out.println(animal+"呼吸水");
}
}
class client_{
public static void main(String[] args){
Terrestrial terrestrial = new Terrestrial();
terrestrial.breathe("牛");
terrestrial.breathe("羊");
terrestrial.breathe("猪");

Aquatic quatic = new Aquatic();
quatic.beathe("鱼");
}
}
/**
* 这样修改花销很大,除了将原来的类Animal分解之外,还需要修改客户端.而直接将
* 修改Animal类虽然违背了单一职责原则,但是花销很小,代码如下:
*/
class Animal_{
public void beathe(String animal){
if("鱼".equals(animal)){
System.out.println(animal+"呼吸水");
}else{
System.out.println(animal+"呼吸空气");
}
}
}

/**
* 这样做client只需要加一句animal.breathe("鱼")这样做很简单,但是存在很大的隐患.如果哪一天鱼要分为淡水鱼和呼吸
* 海水的海水鱼,那么又要修改animal的breathe方法,而对于这个修改可能会对调用猪牛羊的也造成风选,也许哪一天变成
* 猪牛羊也呼吸水了,这种修改方式违背了单一职责原则,虽然改起来简单那,但是隐患很大,还有一种修改方式
*/
class Animal__{
public void beathe1(String animal){
System.out.println(animal+"呼吸空气");
}
public void beathe2(String animal){
System.out.println(animal+"呼吸水");
}
}
/**
* 这样修改了 只需要在client加一句animal.breathe2("鱼"),虽然这样也违背了单一职责原则,但是在方法级别上是符合
* 单一职责原则的,因为并没有动原有的方法的代码.这三种都各有优缺点,但是在实际中采用哪一种还真是比较难说.
* 原则是:只有逻辑足够简单,才可以在代码级别上违反单一职责原则;只有类中方法足够少,才能在方法级别上违反单一职责原则
*
* 例如上面的例子,因为它很简单,所以无论在代码级别上还是方法级别上违反了单一职责原则,都不会造成太大的影响.但是在实际
* 应用中的类都要负责的多,一旦发生职责扩散而需要修改类时,除非这个类本身非常简单,否则还是要遵循单一职责原则的好!
*
* 下面总结单一职责原则的有点:
* 可以降低类的负责度,一个类只负责一个职责,其逻辑肯定要比负责多项职责的简单的多
* 提高类的可读性,提高系统的可维护性
* 变更引起的风险降低,变更时必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响
* 需要说明一点的是单一职责原则不只是对面向对象编程思想所特有的,只要是模块化的程序设计,都适用单一职责原则
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值