a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 164|回复: 0

[基础知识] 最大化Java代码的作用

[复制链接]
发表于 2012-8-4 12:37:27 | 显示全部楼层 |阅读模式
在轨范员中似乎存在着一种日益普遍的不雅概念,认为重用只是一个神话。或许是传统的面向对象编程体例中所存在的不足增添了重用的坚苦。本文介绍了年夜此外一种分歧的路子使重用成为可能的三个轨范。第一步:将功能实现年夜类实例的体例中移出 ( P/ y) z% S# B8 P" H/ P

$ s, m: U8 ]# N# a( H6 @) ?  因为缺乏切确性,类担任不长短常理想的代码重用机制。换句话说,如不美观不担任一个类的数据成员和其他的体例,那么你就无法重用这个类的某个零丁的体例。这些额外的不需要的承担使体例重用的代码变得复杂。派生类对其父类的依靠性也以入了额外的复杂性:对父类的改动会对子类造成影响;当改削肆意矣闽类的时辰,我们很难记得清哪个体例被笼盖,哪个没有;而且被笼盖的体例是否会挪用父类中响应的体例并不很是清楚地闪现。# K# h- h' _& ]& e/ f
  任何执行单一概念使命的体例应该能够成为代码用的首选而自力存在。为了达到这个方针,我们必需会到过程化的编程模式,将代码年夜类实例的体例中移出,形成具有全局可见性的过程。为了提高这种过程的可重用性,过程代码应该象静态的通用体例一样编写:每个过程只能使用自己的输入参数,只能挪用其他全局性的过程完成其工作,不能使用任何非当地的变量。这种对外部依靠的简化降低了过程使用的复杂性,也增添了在其他处所使用此过程的可能性。当然,因为其结构凡是会变得更为清楚,即使抛开重用的目的不谈我们也可以年夜这种代码的组织体例中受益。
$ B. T& w- }; J% b2 @  在Java中,体例不能脱离类而零丁存在。是以,你可以对相关的过程进行组织并使它们成为一个自力的类中的公共静态体例。例如,对于如下所示的一个类:) }* E2 D7 t+ x! u" l
  class Polygon{
+ a: ]8 P: w. v) j; ]' y4 @0 d  …
2 E5 Q4 x/ {2 E/ Z  public int getPerimeter(){…}
/ E3 s, I5 d. B3 u1 {4 N: t  public boolean isConvex(){…}2 t5 V  a9 W" r. f! l/ Q  Y) C- s' L
  public Boolean containsPoint(Point p){…}* M7 z( F- q& H
  …
) l$ A$ V: A$ [  }. {4 e) f3 T1 |
  可以将它改写成下面的形式:1 P# T) B& Y& O$ v2 v# B# T- j
  class Polygon {
  q. h4 r/ Q! Z3 d5 ]0 B6 N* q  t  …
' U) t. o6 X# c2 k- g8 E* U0 H  public int getPerimeter() { return pPolygon.computePerimeter(this);}
, g: H+ @+ t0 x1 |- E  public boolean isConvex() { return pPolygon.isConvex(this);}
5 M7 K* Q) E% R) P8 @  public boolean containsPoint() { return pPolygon.containsPoint(this, p);}
) b5 ]. p9 m6 j* P2 m  …
5 i( V, |$ r- \  }$ X3 V% K- _: G, c; ^
  在此处,nPolygon应该是这个样子:" `, q# F2 N( ~9 J% R( j
  class pPolygon {  a% v$ j9 b! D, q; k
  static public int computePerimeter(Polygon polygon) {...}, r  r# G9 C( X9 S5 Q# ?2 d& z
  static public boolean isConvex(Polygon polygon) {...}
$ M8 G7 j7 D4 s2 E/ B/ C  static public boolean containsPoint(Polygon polygon, Point p) {...}8 r7 Q- l0 ]/ @8 H2 h& o1 a
  }, {0 Z% Z  S6 P. ?( g. }' U
  年夜类的名字pPolygon可以看出,该类所封装的过程首要与Polygon类型的对象有关。名字前面的p暗示该类的独一目的是组织公共静态过程。在Java中,类的名字以小写字母开首不是一种尺度的做法,但象pPloygon这样的类事实上并不执行通俗类的功能。也就是说,它并不代表着一类对象,它只是说话自己所需要的用于代码组织的实体。
' K6 d1 a' J1 v% H7 I7 O  在膳缦沔这个例子中,改动代码的总体影响是使得客户代码不必为了重用其功能而年夜Polygon担任。Polygon类的功能此刻已经由pPolygon类以过程为单元供给。客户代码只使用自己需要的代码,无需关心自身并不需要的功能。3 |7 @8 H7 s7 z! o% G6 l( [6 s5 y
  这并不意味着在这种新型的过程化编程模式中,类不处事于更有用的目的。恰恰相反,类执行组挚租装对象数据成员的需要工作。而且它们经由过程多重接口实现多态性的能力也为代码重用供给了显著的撑持,这将不才一个轨范中谈判。然而,因为将功能实现包含在实例体例中无法实现理想的代码重用,所以经由过程类担任实现代码重用和多态性撑持也不应成为最佳的手艺选择。
5 }7 H! F- ?1 D5 H8 Z" E  在一本被广为阅读的书《Design Patterns》中曾简要地说起一种略有分歧的手艺。策略模式(Strategy Pattern)倡导将相关算法的每个成员封装在一个通用的接口下,以便于客户端代码可交流地使用其算法。因为一个算法凡是被作为一个或几个自力的过程进行编码,这种封装更注重执行零丁使命的过程的重用,而不是执行多种使命的、包含代码和数据的对象的重用。这一轨范浮现了不异的根基思惟。% }4 a" V9 I0 ?, Z- M& E
  然而,将一个算法封装在一个接口下意味着将算法作为实现接口的对象进行编码。这意味着我们仍然依靠于一个与所包装的对象的数据和其他体例相耦合的过程,这样便会使其改暌姑变得复杂。此外还存在这样一个问题,每次需要使用这个算法的时辰都必需实例化这些对象,这便会降低轨范的机能。值得信用的是,设计模式供给了针对这两个问题的解决体例。可以在对策略对象进行编码时应用享元模式(Flyweight Pattern,译者注:还存在一种译法为轻量模式),这样每个对象只会存在一个被共知共享的实例(这针对轨范机能的问题),而且每个共享对象在访谒距离中并不维持状况(于是对象将没稀有据成员,这针对年夜年夜都的耦合问题)。由此发生的享元--策略模式很是近似于在这一轨范中所提到的将功能实现封装在全局可见的、无状况的过程中的手艺。(译者注:以上这两段文字读起来可能有些艰涩难解,建议有乐趣的读者参阅文中所提到《设计模式》一书,Erich Gamma等著、李英军等译、机械工业出书社出书。)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-4-29 22:47 , Processed in 0.260736 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表