前言:

前言:java这种面向对象的的语言其实是很符合人的生活思维模式的,因为它以对象作为自己的研究对象,所谓“万物皆对象”。一个人、一颗苹果、一只蚂蚁都是对象。所以它的设计原则和设计模式都是围绕对象思考之后凝练出来的思想精粹,都具有时间上的稳定性。本节我们就来聚焦java的设计原则,一探java程序设计原则的内幕。

一:单一职则原则

1.1解释:指的是Java在进行类设计的时候,应该让一个类只完成一件具体的事,承担自己单一的职责。只能由一种原因引起自身的变化,也就是说它的功能单一性。具体的属性、方法的设计应该围绕的是如何去完成这个单一的职责,而不管其他功能。

1.2:示例

示例:假如我们现在来完成给用户发邮件这件事,我们来定义这个类,那么这个类就只管发邮件这个动作,至于发送给谁邮件,发送的内容是什么,我们可以用Mail类来完成处理,这个SendMail类根本不去维护这些东西

public class Mail{
private String address;//发送的地址
private String content;//发送的内容
private Person Person;//发送给谁
}
public class SendMail{ //发送邮件
public void send(){
//send mail detail
}
}

引申意义

可以把一个类理解为一个人,社会是由人构成的,社会可以理解为一个大的容器,人是其中的构件。每个人应该让自己的职业单一,尽量只完成自己的任务,拥有“专注”的精神。专攻一个行业,黑客与画家中有这样一句话:“一个人想在某个领域有所建树,必须投入自己所有的全部精力”。让自己全身心投入到一件事中,这样才有可能取得一定的业绩。毕竟一个人的精力是有限的。

二:依赖倒置原则:

2:1:解释:高层组件应该依赖于抽象而不是具体,即应该进行面对接口编程。依赖的成员变量和参数都应该是抽象的而不是具体的。

引申意义:如果映射到现实世界中,可以发现这种现象随处可见。比如在一家企业公司里,高层领导说的话大多是笼统而概念化的。不指向具体的事物,只是泛泛而谈。这样通过层层往下具体的分工,分到每个人身上完成具体的任务,有底层的人物去完成具体的细节

2.2:示例:假如某电商网站正在搞促销,我们需要一个价格的观察器来观察它的价格变化,这个时候我们最好定义一个具体的观察者并且实现Observer接口,这样做的好处就是减少了代码量,可以复用Observer提供的方法。并且维护一个Set集合,这里并不去用具体的集合,成员变量最好是抽象的,这样在对子类进行实现的时候,我们可以自由选择,而不是写死。增加了程序的灵活度,比如后期我们需要对观察的用户进行排序,这样就可以在方法中进行TreeSet的实现,如果不需要为了更高的性能,可以用HashSet作为具体实现:

public class PriceObserver implements Observer
{
private Set<Users> observers; }

  

三:里氏替换原则

3.1解释:凡是父类出现的地方都可以用子类进行代替,并且原功能没有发生变化,即所有引用基类的地方必须能透明地使用其子类的对象。

3.2:示例:这里就不得不提java的多态了,即父类引用指向子类对象,我们来定义个动物类,它具有飞和跑的功能,我们是实现一个子类,叫pig,不过这里就有一个问题了,猪它不会飞(无法实现fly方法),怎么办呢?

public class Animal
{
public absract void fly();
public absract void run();
} public class pig extends Animal
{ @override
public void fly(){ } @override
public void run(){ }
}

修正后如下:为了让父类的方法更具有适用性和伸缩度,我们应该添加一个参数来判断它时候是否能进行:

public class Animal
{
public absract void fly(boolean able);
public absract void run(boolean able);
}

 简单而言它有以下几个我们必须遵守的:

  • 子类可以实现父类的抽象方法,但是不能覆盖父类的非抽象方法。
  • 子类中可以增加自己特有的方法。
  • 当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
  • 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

3.3:引申意义:这也应了一句话:长江后浪推前浪,前浪死在沙滩上。儿子继承了父亲的衣钵,一般拥有父亲的能力。当然这句话并不严谨,我们看到很多故事中,一般父亲做的职业,都不会让儿子继续干。关于这里我想从另一方面去理解,那就是学习能力。可以把老师理解为父类,学生理解为子类,子类去实现父类的方法,提高自己的学习能力,通过最后的学习拥有老师的知识和财富。

四:迪米特原则

4.1:解释:一个类应该尽量的封装自己,与自己的朋友类打交道,一般朋友类都是成员变量和参数,非朋友类是局部参数.

4.2:示例:假如我们来设计一个设备开启的方法封装类,它内部含有多个细节,比如接通电源、开启设备的运行状态、开启设备的屏幕显示、开启声音驱动,这时候我们就要尽可能的封装它,向外暴露出简单易用的api:

public class OpenDevice {

    private MediaHelper mediaHelper;

    private void openPowerSource(){
System.out.println("开启电源...");
} public void open(){ //只向外暴露总的开启方法 而不暴露具体的开机细节
openPowerSource();
mediaHelper.openMedia();
} }
public class MediaHelper { //朋友类

    private void openScreen(){
System.out.println("开启屏幕");
} private void openSound(){
System.out.println("开启声音");
} public void openMedia(){//封装两个private方法,将其权限增大为public向外暴露
openScreen();
openSound();
}
}

简单而言它有以下几个我们必须遵守的:

  • 自己本类的成员变量尽量设置为private的,降低外界的访问权限
  • 自己本类的方法尽量为private的,只暴露业务逻辑上的改口方法,而不是技术细节内部的方法
  • 如果朋友类有间接的引用,这时候应该隐藏间接引用,不从中间暴露。我们可以新增一个中间类来管理所有的需要类

引申意义:一个人应该尽量的完善自己,尽量与自己朋友之间来往,不要过渡的依赖别人,应该保证自己的独立性,或者拒绝与外部陌生人打交道。这是“安全”策略,实现与外部的连接很有可能会有一定的风险。就好比有些孩子本性纯良,被一些社会上的不三不四的人带着误入歧途(比我的表弟)。当然并不能理解为封心,拒绝与外部交流。这样只会生活在一个狭小的区域范围内,看不到外面的风景,会让自己的视野变的窄而短。从而目光短浅。软件设计中有一个追求的特性是:高内聚,低耦合。一个人应该尽可能的完善自己,而尽量减少与其他人的联系。有句话叫做“你若盛开,蝴蝶自来”。这里的盛开可以理解为“内聚”性。让自己的能力聚集起来,绽放出最美丽的自己。

五:接口隔离原则

解释:一个接口尽可能的功能单一化,不要承担过多的责任。

示例:这里可以用spring的BeanFactory类来说明问题:

beanFactory 是Spring bean容器的根接口.提供获取bean,是否包含bean,是否单例与原型,获取bean类型,bean 别名的api.其核心功能在于bean的管理上

AutowireCapableBeanFactory 添加集成其他框架功能.如果集成WebWork则可以使用Spring对Actions等进行管理.主要用于其他地方引用BeanFactory

HierarchicalBeanFactory 提供父容器的访问功能,主要功能在于父容器的操作上

ConfigurableBeanFactory 如名,提供factory的配置功能,主要负责配置bean

ConfigurableListableBeanFactory 集大成者,提供解析,修改bean定义,并与初始化单例.

ListableBeanFactory 提供容器内bean实例的枚举功能.这边不会考虑父容器内的实例.

可以看到BeanFactory向下的接口中都有各自的职责,之间分别划分具体的功能和职责,互不影响,每个接口完成自己本身的任务。

应该遵守以下几条原则:

  • 接口尽量小,但是要有限度。对接口进行细化可以提高程序设计灵活性,但是如果过小,则会造成接口数量过多,使其太过复杂,所以一定要适度。
  • 为依赖接口的类定制服务,只暴露给调用的类它需要的方法,它不需要的方法则隐藏起来。只有专注地为一个模块提供定制服务,才能建立最小的依赖关系。
  • 提高内聚,减少对外交互,在有限的范围内使接口用最少的方法去完成最多的事情。

引申意义:这点其实和职责单一有异曲同工之秒。不过一个说的是类,一个说的是接口。接口和类是两个不同的概念,一个是实体东西,一个是抽象功能概括。这里就想多谈谈职责这个问题,而类中我谈的是职业。职责中自己应该具体专攻一方面,而不是太多的东西,上文提到过我们的精力有限,承担的具体职责也是有限的,应该尽可能的让自己承担少,这样才能更好的完成目前的工作。除非有多余的精力,才可以去探索各种东西。

六:开闭原则

Java:对扩展开放,对修改闭合。对于一个系统来说,应该拥有一套良好的扩展性,方便进行功能的扩展,而不会影响到具体的其他组件。任何事情都要防患于未然。当进行功能的扩展时候,尽量不要修改原代码,不要改动原来的东西。

简而言之,它需要我们做出以下:

1:通过接口或者抽象类约束扩展,对扩展进行边界限定,不允许出现在接口或抽象类中不存在的public方法;

2:参数类型、引用对象尽量使用接口或者抽象类,而不是实现类;

3:抽象层尽量保持稳定,一旦确定即不允许修改。

引申意义:我从这点悟到的是,和一个人交流的时候应该做的是不要随意批判一个人,不要尝试去改变一个人,我没有那么大的权利,也没有那么大的能力去指指点点别人的生活。尽量的不要修改,如果想可以原基础上进行其他方面的扩展。比如对兴趣的延伸,新大陆的开展。毕竟每个人都不是傻子,每个人都拥有自己的生活空间,不要擅自的去修改。还有另一方面,一个人应该不断的扩展自己的能力。

 总结

本篇博文主要介绍了java的程序设计的六大原则,记住软件设计的一个核心思想就是:高内聚、低耦合。无论怎样的手段和措施,我们都是在朝着这两个目标发展。在平时的程序开发过程中,我们应该严格按照这些设计原则,这样设计出来程序的更加具有复用性和健壮性的特点,也对我们的程序开发更加具有指导性。

java程序设计原则的更多相关文章

  1. java程序设计原则知多少

    程序设计七大原则 一.开闭原则 ​ 针对我们设计的功能模块对扩展开放,对修改关闭:利用面向接口(抽象)编程(多态的特性),实现对功能需求扩展的同时,不允许更改原来的代码.提高对象的可复用性.可维护性. ...

  2. 2016-2017-2 《Java程序设计》教学进程

    2016-2017-2 <Java程序设计>教学进程 目录 考核方式 课前准备 教学进程 第00周学习任务和要求 第01周学习任务和要求 第02周学习任务和要求 第03周学习任务和要求 第 ...

  3. 2016-2017-2 《Java程序设计》预备作业2总结

    2016-2017-2 <Java程序设计>预备作业2总结 古希腊学者普罗塔戈说过:「头脑不是一个要被填满的容器,而是一束需要被点燃的火把.」 在对计算机系的学生情况的调查中,我说: 最近 ...

  4. 《程序设计教学法--以Java程序设计为例》

    <程序设计教学法--以Java程序设计为例> 当老师上的第一门课就是<Java程序设计>,工作以来,断断续续上了近十次课了吧.十几年来,教材.课程内容.教学方法.教学手段不断改 ...

  5. 2015-2016-2 《Java程序设计》教学进程

    2015-2016-2 <Java程序设计>教学进程 目录 考核方式 寒假准备 教学进程 第00周学习任务和要求 第01周学习任务和要求 第02周学习任务和要求 第03周学习任务和要求 第 ...

  6. 20145212 《Java程序设计》第4周学习总结

    20145212 <Java程序设计>第4周学习总结 教材学习内容总结 第六章知识点: 1.继承基本上就是避免多个类间重复定义的行为. 2.子类继承父类,通过继承,我们可以避免类间的重复定 ...

  7. 20145213《Java程序设计》实验三敏捷开发与XP实践

    20145213<Java程序设计>实验三敏捷开发与XP实践 实验要求 1.XP基础 2.XP核心实践 3.相关工具 实验内容 1.敏捷开发与XP 软件工程是把系统的.有序的.可量化的方法 ...

  8. 20145213《Java程序设计》实验二Java面向对象程序设计实验报告

    20145213<Java程序设计>实验二Java面向对象程序设计实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装,继承,多态 初步掌握UML建模 熟悉S.O. ...

  9. 20145206《Java程序设计》第10周学习总结

    20145206 <Java程序设计>第10周学习总结 博客学习内容总结 什么是网络编程 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就是把数据发送到指定 ...

随机推荐

  1. angular 4 http 之web api 服务

    Angular Http是获取和保存数据的.主要是为了取到我json文件里的数据. 直接上代码吧: 1.  先介绍Promise模式的:(直接代码) heroes.json: 1 2 3 4 5 6 ...

  2. JAVA异步加回调的例子

    package com.sunchao.callback; /** * callback interface * @author Administrator * */ public interface ...

  3. docker结合jenkins、gitlab实现.netcore的持续集成实践

    本文的目标是实现下图基于ASP NET Core的实践 运行环境 Cent OS 7 vs code .net core cmder 运行docker,设置docker镜像加速器,不然国内下载imag ...

  4. requests关于Exceeded 30 redirects问题得出的结论

    昨天一个朋友在爬网页时出现的一个问题,以及后续我对这个问题进行了简单的测试. 先说出现的问题的简单描述. 首先是使用urllib请求网页: #urllib.request发起的请求 import ur ...

  5. Django 类方式view进行进行用户验证

    问题: Django中,view的书写方式有两种,一种是def函数方式,一种是class方式,函数方式通过@login_required装饰器标记函数,就必须通过用户验证,而类,则没办法通过此方法进行 ...

  6. linux指令--ls

    本篇博客转自http://www.cnblogs.com/peida/archive/2012/10/23/2734829.html,在原作者基础上做了修改和总结. ls命令是linux下最常用的命令 ...

  7. 解决eclipse maven工程中src/main/resources目录下创建的文件夹所显示样式不是文件夹,而是"包"图标样式的问题

    参考:http://blog.csdn.net/luwei42768/article/details/72268246 eclipse项目中创建maven项目后,有时在执行命令maven update ...

  8. 理解JS中的call、apply、bind方法(*****************************************************************)

    在JavaScript中,call.apply和bind是Function对象自带的三个方法,这三个方法的主要作用是改变函数中的this指向. call.apply.bind方法的共同点和区别:app ...

  9. 解决ubuntu系统root用户下Chrome无法启动问题

    由于ubuntu16.04系统自带的是Firefox浏览器,需要安装Chrome浏览器,但是在root用户下安装后发现,Chrome无法正常启动.安装及问题解决具体如下: 1. ubuntu上Chro ...

  10. 【转】awk 里的substr函数用法举例

    awk 里的substr函数用法举例: 要截取的内容:2007-08-04 04:45:03.084 - SuccessfulTradeResult(status: 1, currencyPair: ...