面向对象开发与面向对象设计模式的几个核心的思想和概念 -java

  面向对象方法,OO方法所具有的模块化、信息封装与隐蔽、抽象性、继承性、多样性等独特之处,这些优异特性为研制大型软件、提高软件可靠性、可重用性、可扩充性和可维护性提供了有效的手段和途径。Java主要特征:封装性,继承性,多态性.

>>>> 面向对象开发的几个核心思想

1、问题领域、对象、属性、状态、行为、方法、实现

问题领域:
  指软件系统所模拟的真实世界中的系统,在现实生活中,比较常见的比如,税收、社保、银行、商场等等,都可以使用软件来进行模拟,这些就是软件所针对的问题领域。

对象:对象是对问题领域中的事物的一种抽象。
1)所有的东西都是对象,万物皆对象,问题领域中的实体和概念都可以抽象为对象。
2)世界上没有完全相同的两片叶子,每个对象都是唯一的,对象的唯一性来自于真实世界中的事物的唯一性,即使在系统中java的两个对象,内存地址也未必相同。
3)每个对象具有属性和行为。
4)每一个对象都具有状态,状态的意思就是在某一个时间点上,对象的各个属性的取值情况。
5)对象都属于一个类,每个对象都是某一个类的实例,类是具有相同属性和行为的对象的集合,同一个类的所有的实例都具有相同的属性,表示他们的属性的含义是相同的,但是他们的状态未必是相同的,也就是属性的取值未必是一样的。

2、类、类型
类:
 类是一组具有相同属性和行为的对象的抽象。类以及类的关系构成了对象模型的主要内容。
 面向对象变成的主要任务就是定义对象模型中的各个类。
 对象是类的实例,类是对象的模板。

3、消息、服务
消息可以理解为参数,服务,就是方法返回的值。

4、接口
什么是接口?
  对象,通过接口对提供服务。在现实的世界中,接口是实体,但是在面向对象的范畴中,接口是一个抽象的概念,指的是系统对外提供的服务。系统的接口描述系统能够提供哪些服务,但是不包含服务的实现的细节。对象是最小的子系统,每个对象都是服务提供者,因此每一个对象都具有接口。
  站在使用者的角度上,对象中所有向使用者公开方法的声明构成了对象的接口。使用者调用对象的公开方法来获得服务,使用者在获得服务的时候,不需要关心对象到底是如何实现服务的。
  接口,是实现系统之间松耦合的有力手段。
  计算机系统也是一个充分利用接口来提高系统松耦合的例子,接口还提高了系统的可扩展性。

在java语言中,接口有两个方面的意思:
  1)接口是指概念性的接口,也就是系统对外提供的所有的服务,在对象中表现的是public类型的方法的声明。
  2)是指interface为关键字定义的实实在在的接口,也成为接口类型,用于明确的描述系统所提供的服务,能够更加清晰的把系统的实现细节与接口分离。

5、封装、透明
封装
  封装是指隐藏对象的属性和实现的细节,仅仅对外公开接口,封装能够带来的优点如下:
1)便于使用者能够正确、方便的理解和使用系统,防止使用者错误修改系统的属性。
2)有助于建立各个系统之间的松耦合关系,提高系统的独立性,当一个系统的实现发生变化的时候,只要她的接口不发生变化,就不会影响到其他的系统。
3)提高系统的可重用性,每个系统都是一个相对独立的整体,可以在多种环境中得到重用。
4)降低了构建大型系统的风险,就类似于搭积木一样,个别的系统不成功,但是代码还是可以被重用的。

一个设计良好的系统会封装所有的实现细节,把它的接口与实现能够清晰的隔离起来,系统之间只通过接口进行通信。面向对象的编程语言主要通过访问控制机制来进行封装,   这种机制能够控制对象的属性和方法的可访问性。在java语言中提供了如下四种方式的访问级别:
  public(公开)private(私有)protected(同一个包、子类)default(同一个包)
  把尽可能多的东西藏起来,然后对外提供间接的接口,如果封装的程度越高,那么相对的独立性就越高,这样使用起来就会更加的方便。
  把所有的属性封装起来,至少有几个好处:更符合客观世界规律、更灵活的控制属性访问级别、防止用户错误操作、有助于对象封装实现细节。

6、抽象
抽象:
  从特定的角度出发,从已经存在的一些事物当中抽取我们所关注的细节,形成一个新的事物的思维过程。抽象是一种从具体到抽象、由复杂到简单的思维方式。
  三种类型的抽象:
1)从问题领域到软件模型中的对象的抽象
2)从对象到类的抽象
3)从子类到父类的抽象

在java语言中,抽象有两种意思:
1)抽象,是一种思维过程,包含上面三种方式的抽象
2)抽象,是一个形容词,可以用来修饰类以及方法,如果一个方法被abstract修饰的话,则说明这个方法没有被具体实现,如果一个类被abstract修饰,则说明这个是抽象类,不能被实例化。

7、继承、扩展、覆盖
  在父类和子类之间同时存在着继承和扩展的关系。子类继承父类的属性以及方法,同时子类中还可以扩展出新的属性以及方法,并且还可以覆盖父类当中方法的实现方式。
  继承与扩展同时提高了系统的可重用性和可扩展性。公有继承 私有继承 保护继承
  继承与扩展导致了面向对象软件开发领域中的架构类软件系统的发展。

如何在一些通用的软件架构的基础上进行扩展呢?
  这些通用的软件架构中都提供了一些扩展点,简单的说,这些扩展点就是为了让用户进行继承和扩展的类。这些类已经具备了一些功能,并且能够和软件中的其他的类能够进行紧密的协作,用户只需要创建这些类的子类,然后在这些子类中增加新的功能或者是重新实现某些功能,用户定义的子类能够和系统中原有的类进行和谐融洽的协作。
  比如:J2EE、Servlet、JSP、EJB、Struts、JSF、Spring这些都是一些通用的架构。

8、组合
   组合 是一种用多个子系统来组装出复杂系统的有效的手段。
  对于一个组合系统,组合系统和他的子系统是聚集关系,子系统之间则是关联关系或者是依赖关系(在UML中的定义)

面向对象的范畴中,组合具有以下的特点:
 1)在软件的分析和设计的阶段,简化为复杂系统建立对象的模型。在建立对象模型的时候,通常首先识别问题领域的粗粒度对象,然后对该对象进行分解,比较符合人类的思维。
 2)在软件编程的阶段中,假话创建复杂系统的过程,只需要分别创建独立的子系统,然后将其组合起来,就构成了一个复杂的系统。而且允许第三方参与系统的建设,提高了构架复杂系统的效率。
 3)向使用者隐藏系统的复杂度。
 4)提高程序代码的可重用性,一个独立的子系统可以被组合到多个复杂的系统当中。

9、多态、动态绑定
  多态,是指系统A访问系统B提供的服务的时候,系统B可以通过多种方式来提供服务,而这一切对于系统A是透明的。
  动态绑定,一个接口=new 实现类,这个实现类在运行的时候并不知道,可能是实现类A,也可能是实现类B,java虚拟机的这种运行机制被称为动态绑定。
  抽象机制和动态绑定机制能够提高系统之间的松耦合性。

需要注意的一点是:抽象机制是开发人员在开发过程当中使用的机制,但是动态绑定机制是在java虚拟机运行的过程中提供的机制。

>>>> 面向对象设计模式的几个核心思想: 高聚合低耦合

  面向对象,将世界归纳为一句话:万事万物皆对象。
  在没有面向对象之前,软件的可维护性是相当的烂,主要原因有四个:过于僵硬;过于脆弱;复用率低;黏度过高
  在软件设计过程当中无论那种设计思维都把可拓展性、灵活性、可插入性作为软件设计的一个基本的指导思想。

  设计模式的研究当中一个非常重要的概念就是:复用,那么什么是复用呢?软件的复用又有那些好处呢?复用又有那些基本的形式呢?复用和可拓展性、灵活性、可插入性又有那些关联或者关系呢?
  首先,复用就是重复使用的意思。软件复用带来了几个比较明显的好处:1,较高的生产率,2.较高的软件质量,3.恰当的使用复用可以改善软件的系统的可维护性。
  一个可复用的软件可以为将来的软件开发节省开发使用的时间和费用,一个越频繁使用的构件那么以后开发投资就相对越少。如果一个软件的复用路越高,那么发现它存在的缺陷就更快,从而也可以更为彻底的排除这种缺陷,这样很明显有利于系统的维护。更为重要的一点是,复用与系统的可维护行有着直接的关系。
  软件复用包括:代码的复制与粘贴;算法的复用;数据结构的复用,模型复用。

    在面向对象的语言当中数据的抽象化和继承的关系使得概念和定义可以复用;多态性使得实现和应用可以复用。而抽象化和封装可以保证和促进系统的可维护性。面向对象的复用的焦点不是函数不是算法等细节,而是体现在宏观意义上的商业逻辑的抽象的层次上,而这些是提高复用性和保证提高可维护性的关键所在。
    在面向对象的设计当中,抽象的层次应该是相对稳定的部分,也是复用的焦点,抽象模块相对于具体的模块独立,从而具体模块的内部结构的变化就不会影响到抽象层次的结构,因而抽象层次的模型复用就会较为容易。

  在面向对象的领域里边,可维护性复用是以设计原则和设计模式为基础的。
系统的可拓展性由:开闭原则,里氏代换原则,依赖倒转原则和组合/聚合复用原则所保证。
系统的灵活性由:  开闭原则、迪米特法则、接口隔离原则所保证
系统的可插入性由:开闭原则、里氏代换原则,组合/聚合复用原则以及依赖倒转原则所保证。

>>> 1.开闭原则
  开闭原则的核心我们总结为:对拓展开放,对修改关闭。说的直白点就是:在模块不被修改的的前提下可以被拓展。
 优点:
  通过拓展,可以提供新的行为,以满足新的需求,使其具有一定的灵活性和适应性。
  对已有模块,特别是最为重要的抽象模块不能再被修改,使得变化中的软件有一定的稳定性和延续性。
  在开闭原则当中最为关键的就是:抽象化。从另外一个角度讲就是所谓的“对可变性的封装原则”。这样就意味着有两点:
  1、可变性不应该散落到代码的角落,而应该白封装到对象里。继承不应当被看作是封装变化的方法,而应该被认为是从一般的对象生成特殊对象的方法。
  2、一种可变性,不应当与另一种可变性混合(设计模式的类图和继承结构一般都不会超过两层)。

>>> 2.里氏代换原则是继承和复用的一个基石。
  里氏代换原则:任何基类可以出现的地方,子类一定可以出现。
  这个是对开闭原则的一个补充。开闭原则的关键是抽象化,里氏代换原则则是对实现抽象化具体步骤的规范化。

>>> 3.依赖倒转原则
  核心是:依赖于抽象,而不依赖于具体的实现。开闭原则是目标,依赖倒转原则是一种手段。违反了依赖倒转原则就不可能达到开闭原则的要求。

>>> 4.合成/聚合复用原则
  核心:尽量合成/聚合,而不是使用继承关系达到复用的目的。合成/聚合复用原则和里氏代换原则相辅相成,前者要求设计师首先考虑合成和聚合关系,后者则要求在使用继承关系的时候,必须确定这个关系符合这一条件。

  依赖也叫耦合,耦合分为三种,零耦合(如果两个类没有耦合关系),具体耦合(发生在两个具体的或者说是可以实例化的类之间,经由一个类对另一个具体类的直接引用造成的),抽象耦合(发生在一个具体的类和一个抽象类或者接口之间的,使两个必须发生关系的类之间存在最大的灵活性)。

抽象不应当依赖与细节,而细节应当依赖于抽象。也就是针对接口编程,而不要针对实现编程。以抽象的方式耦合是依赖倒转原则的关键。里氏代换原则是依赖倒转原则的一个基础。
 
  组合/聚合复用原则
    核心:要尽量使用合成聚合,尽量不要使用继承。
    聚合用来表示“拥有”关系或者整体与部分的关系。而合成是一种表示强的多的“拥有”关系。上以篇博文中有提及这两者的区别。

>>> 5.迪米特法则
    核心:一个软件的实体应当尽可能的减少和其他实体发生相互作用。
    迪米特法则所谈论的就是对对象之间的信息量、流线以及信息的影响的控制。在软件系统当中,一个模块设计的好不好的最主要也是最重要的标识就是该模块在多大程度上将自己的内部数据和其他有关的细节隐蔽起来。

  在类的划分上应当创建有弱耦合的类;
  在类的设计结构上,每一个类都应当尽量降低成员的访问权限,一个类不应当public自己的属性而应该提供取值和赋值的方法。 
在类的设计上,只要有可能就应当设置成不变类。
在对其他类的引用上,一个对象对其他对象的引用应当降到最低。


>>> 6.接口隔离原则
  核心:客户端应该尽可能小的单独的接口,而不要提供大的总的接口。
  接口隔离原则和广义的迪米特法则都是对一个软件的实体与其他的软件实体的通信的限制。广义的迪米特法要求尽可能的减少通信的宽度和深度,接口隔离原则限制的是通信的宽度。遵循这两个法则会使一个系统软件,在功能拓展的过程当中,不会将修改的压力传递到其他对象。

    以上就是设计模式当中应该注意的几个原则,也是指导设计的一个关键性的原则。在设计软件的时候,应该充分的考虑这几个基本原则,同时也要考虑到软件或者其他工具本身,以及软件经济成本和时间成本等因素的一些制约,所以需要综合来考虑分析,用最合适的方式来开发和维护软件,避免成本虚高,设计过度的情形出现,总之,在允许的条件情况下用最合的的设计模式进行软件开发是最值得推荐的。

你可能感兴趣的:(Java,Web/J2EE,Java,base)