http://www-128.ibm.com/developerworks/cn/opensource/os-ecl-ajax/index.html?S_TACT=105AGX52&S_CMP=techcsdn
posted @
2006-09-07 13:42 Dave 阅读(158) |
评论 (0) |
编辑 收藏
http://www.sergiopereira.com/articles/prototype.js.html
posted @
2006-08-10 15:06 Dave 阅读(208) |
评论 (0) |
编辑 收藏
http://blog.csdn.net/calvinxiu/archive/2006/08/08/1036306.aspx
posted @
2006-08-10 13:02 Dave 阅读(173) |
评论 (0) |
编辑 收藏
http://java.csdn.net/n/20060807/93375.html
posted @
2006-08-10 13:01 Dave 阅读(185) |
评论 (0) |
编辑 收藏
http://java.csdn.net/n/20060808/93473.html
posted @
2006-08-10 12:59 Dave 阅读(269) |
评论 (0) |
编辑 收藏
https://compdoc2cn.dev.java.net/prototype/html/prototype.js.cn.html
posted @
2006-08-10 12:50 Dave 阅读(196) |
评论 (0) |
编辑 收藏
定义:一个正则表达式,就是用某种模式去匹配一类字符串的一个公式。
正则表达式由一些普通字符和一些
元字符(metacharacters)组成。普通字符包括大小写的字母和数字,而元字符则具有特殊的含义,我们下面会给予解释。
元字符 | | 描述 |
---|
| |
|
. | | 匹配任何单个字符。例如正则表达式r.t匹配这些字符串:rat、rut、r t,但是不匹配root。 |
$ | | 匹配行结束符。例如正则表达式weasel$ 能够匹配字符串"He's a weasel"的末尾,但是不能匹配字符串"They are a bunch of weasels."。 |
^ | | 匹配一行的开始。例如正则表达式^When in能够匹配字符串"When in the course of human events"的开始,但是不能匹配"What and When in the"。 |
* | | 匹配0或多个正好在它之前的那个字符。例如正则表达式.*意味着能够匹配任意数量的任何字符。 |
\ | | 这是引用府,用来将这里列出的这些元字符当作普通的字符来进行匹配。例如正则表达式\$被用来匹配美元符号,而不是行尾,类似的,正则表达式\.用来匹配点字符,而不是任何字符的通配符。 |
[ ] [c1-c2] [^c1-c2] | | 匹配括号中的任何一个字符。例如正则表达式r[aou]t匹配rat、rot和rut,但是不匹配ret。可以在括号中使用连字符-来指定字符的区间,例如正则表达式[0-9]可以匹配任何数字字符;还可以制定多个区间,例如正则表达式[A-Za-z]可以匹配任何大小写字母。另一个重要的用法是“排除”,要想匹配除了指定区间之外的字符——也就是所谓的补集——在左边的括号和第一个字符之间使用^字符,例如正则表达式[^269A-Z] 将匹配除了2、6、9和所有大写字母之外的任何字符。 |
\< \> | | 匹配词(word)的开始(\<)和结束(\>)。例如正则表达式\<the能够匹配字符串"for the wise"中的"the",但是不能匹配字符串"otherwise"中的"the"。注意:这个元字符不是所有的软件都支持的。 |
\( \) | | 将 \( 和 \) 之间的表达式定义为“组”(group),并且将匹配这个表达式的字符保存到一个临时区域(一个正则表达式中最多可以保存9个),它们可以用 \1 到\9 的符号来引用。 |
| | | 将两个匹配条件进行逻辑“或”(Or)运算。例如正则表达式(him|her) 匹配"it belongs to him"和"it belongs to her",但是不能匹配"it belongs to them."。注意:这个元字符不是所有的软件都支持的。 |
+ | | 匹配1或多个正好在它之前的那个字符。例如正则表达式9+匹配9、99、999等。注意:这个元字符不是所有的软件都支持的。 |
? | | 匹配0或1个正好在它之前的那个字符。注意:这个元字符不是所有的软件都支持的。 |
\{i\} \{i,j\} | | 匹配指定数目的字符,这些字符是在它之前的表达式定义的。例如正则表达式A[0-9]\{3\} 能够匹配字符"A"后面跟着正好3个数字字符的串,例如A123、A348等,但是不匹配A1234。而正则表达式[0-9]\{4,6\} 匹配连续的任意4个、5个或者6个数字字符。注意:这个元字符不是所有的软件都支持的。 |
posted @
2006-08-07 17:06 Dave 阅读(162) |
评论 (0) |
编辑 收藏
public aspect TraceAspect{
private Logger _logger = Logger.getLogger("trace");
pointcut traceMethods(): execution(* *.*(..))&&!within(TraceAsptect);
before() : traceMethods(){
Signature sig = thisJoinPointStaticPart.getSignature();
_logger.logp(Level.INFO, sig.getDeclaringType().getName(), sig.getName(), "Entering");
}
}
What’s wrong with conventional logging ?
When a new module is added to the system, all of its methods that need logging must be instrumented. Such instrumentation is invasive, causing the tangling of the core concerns with the logging concern. Further, if you ever happen to change the logging toolkit to a different API, you need to revisit every logging statement and modify it.
Consistency is the single most important requirement of logging. It means that if the logging specification requires that certain kinds of operations be logged, then the implementation must log every invocation of those operations. When things go wrong in a system, doubting the logging consistency is probably the last thing you want to do. Missed logging calls can make output hard to understand and sometimes useless. Achieving consistency using conventional logging is a lofty goal, and while systems can attain it initially, it requires continuing vigilance to keep it so. For example, if you add new classes to the system or new methods in existing classes, you must ensure that they implement logging that matches the current logging strategy.
The beauty of AspectJ-based logging
The limitations are not a result of the logging APIs or their implementations; rather, they stem from the fundamental limitations of objectoriented programming, which require embedding the logging invocations in each module. AOP and AspectJ overcome those limitations. AspectJ easily implements the invocation of logging statements from all the log points. The beauty is that you do not need to actually instrument any log points; writing an aspect does it automatically. Further, since there is a central place to control logging operations, you achieve consistency easily.
The most fundamental difference between conventional logging and AspectJbased logging is modularization of the logging concern. Instead of writing modules that implement core concepts in addition to invoking logging operations, with AspectJ you write a few aspects that advise the execution of the operations in the core modules to perform the logging. That way, the core modules do not carry any logging-related code. By modularizing, you separate the logging concern
from the core concerns.
With AspectJ-based logging, the logger aspect separates the core modules and the logger object. Instead of the core modules’ embedding the log() method invocations in their source code, the logger aspect weaves the logging invocations into the core modules when they are needed. AspectJ-based logging reverses the dependency between the core modules and the logger; it is the aspect that encodes how the operations in the core modules are logged instead
of each core module deciding for itself.
posted @
2005-08-29 10:52 Dave 阅读(788) |
评论 (2) |
编辑 收藏
泛型的引入使得 Java 语言中的类型系统更加复杂。以前,该语言具有两种类型 —— 引用类型和基本类型。对于引用类型,类型 和类 的概念基本上可以互换,术语子类型 和子类 也可以互换。
随着泛型的引入,类型和类之间的关系变得更加复杂。List<Integer>
和 List<Object>
是不同的类型,但是却是相同的类。尽管 Integer
扩展 Object
,但是 List<Integer>
不是 List<Object>
,并且不能赋给 List<Object>
或者强制转换成 List<Object>
。
另一方面,现在有了一个新的古怪的类型叫做 List<?>
,它是 List<Integer>
和 List<Object>
的父类。并且有一个更加古怪的 List<? extends Number>
。类型层次的结构和形状也变得复杂得多。类型和类不再几乎是相同的东西了。
extends 的新含意
在 Java 语言引入泛型之前,extends
关键字总是意味着创建一个新的继承自另一个类或接口的类或接口。
引入泛型之后,extends
关键字有了另一个含意。将 extends
用在类型参数的定义中(Collection<T extends Number>
)或者通配符类型参数中(Collection<? extends Number>
)。
当使用 extends
来指示类型参数限制时,不需要子类-父类关系,只需要子类型-父类型关系。还要记住,有限制类型不需要是该限制的严格子类型;也可以是 该限制。换句话说,对于 Collection<? extends Number>
,您可以赋给它 Collection<Number>
(尽管 Number
不是 Number
的严格子类型)和 Collection<Integer>
、Collection<Long>
、Collection<Float>
等等。
在任何这些含意中,extends
右边的类型都可以是参数化类型(Set<V> extends Collection<V>
)。
posted @
2005-08-24 11:36 Dave 阅读(186) |
评论 (0) |
编辑 收藏
Eclipse 运行命令行参数大全
包括英文版本和中文版本两种的说明, 特别需要值得一提的是那个 -nl 参数, 可以指定程序启动时所使用的语言. 例如:
eclipse -nl en_US
将启动英文语言, 这个特性在安装了国际化语言包以后特别有用, 可以方便的切换各个语言的版本. 注意 IBM WSAD v5.1 也支持这个功能.
运行 Eclipse
将 Eclipse 驱动程序安装(解压缩)到某个目录(例如,c:\eclipse)中之后,通过运行顶级安装目录中的 Eclipse 可执行文件来启动"工作台"。在 Windows 系统上,该可执行文件称为 eclipse.exe,而在 Linux 系统上称为 eclipse。注意:下列讨论描述 Windows 系统上的设置。Linux 上的设置是相似的。
如果您没有另行指定,则平台将缺省工作区目录创建为可执行文件的兄弟目录(例如 c:\eclipse\workspace)。此工作区目录用作项目的缺省内容区,还用于保存任何必需的元数据。要进行共享安装或多工作区安装,应明确指出工作区的位置而不是使用缺省值。有两种控制工作区位置的方法:使用当前工作目录或使用 -data 命令行自变量。
将工作区位置设置为在当前工作目录内
在此方案中,工作区位置将是当前工作目录中称为 workspace 的目录。
实现此目的最容易的方法可能是使用下列步骤来创建快捷方式:
导航到 Windows 资源管理器中的 eclipse.exe 并使用右键拖动来创建 eclipse.exe 的快捷方式。
编辑快捷方式的属性,以使启动位置:字段标识工作区位置的父目录(例如,c:\users\robert)。
关闭属性对话框并双击快捷方式(如果提供的目录为 c:\users\robert,则工作区位置将为 c:\users\robert\workspace)。
当然,您也可以使用命令提示符(通过将目录切换为工作区父目录然后运行 eclipse.exe)来获得同样的效果。
使用 -data 设置工作区的特定位置
要使用 -data 命令行自变量,只要将 -data your_workspace_location(例如,-data c:\users\robert\myworkspace)添加至快捷方式属性中的目标字段或显式地将它包括在命令行上。
使用 -vm 设置 java VM
建议显式指定在运行 Eclipse 时要使用哪个 Java VM。使用 -vm 命令行自变量(例如,-vm c:\jre\bin\javaw.exe)可以实现此目的。如果不使用 -vm,则 Eclipse 将使用在 O/S 路径上找到的一个 Java VM。当安装其它产品时,它们可更改您的路径,导致在下一次启动 Eclipse 时使用另一 Java VM。
运行 Eclipse 中的高级主题
Eclipse 可执行文件及平台本身提供了人们感兴趣的开发或调试 Eclipse 各部件的许多执行选项。运行 Eclipse 可执行文件的一般格式是:
eclipse [platform options] [-vmargs [Java VM arguments]]
Eclipse 启动参数 命令 描述 原因
-arch architecture
定义 Eclipse 平台在其上运行的处理器体系结构。Eclipse 平台通常使用 Java os.arch 属性的常用值来计算最佳设置。如果在此处指定该项,则这是 Eclipse 平台使用的值。此处指定的值可作为 BootLoader.getOSArch() 用于插件。示例值有:"x86"、"sparc"、"PA-RISC"和"ppc"。 2.0
-application applicationId
要运行的应用程序。应用程序由向 org.eclipse.core.runtime.applications 扩展点提供扩展的插件来声明。通常不需要此自变量。如果指定了此项,则该值会覆盖配置提供的值。如果不指定此项,则会运行"Eclipse 工作台"。 1.0
-boot bootJarURL
(建议不使用;用 -configuration 代替;支持 1.0 兼容)。Eclipse 平台的引导插件代码(boot.jar)的位置,表示为 URL。如果指定此项,则会用它来为装入 Eclipse 平台引导程序类装入器的类装入器设置类路径。仅当更改 startup.jar 和 boot.jar 的相对位置时才需要它。注意,不允许使用相对 URL。 *1.0
-classloaderproperties [file]
如果指定的话,则使用给定位置处的类装入器属性文件来激活平台类类装入器增强。文件自变量可以是文件路径或 URL。注意,不允许使用相对 URL。单击此处以获得更多详细信息。 2.0.2
-configuration configurationFileURL
Eclipse 平台配置文件的位置,表示为 URL。配置文件确定 Eclipse 平台、可用插件集和主要功能部件的位置。注意,不允许使用相对 URL。当安装或更新 Eclipse 平台时配置文件被写至此位置。 2.0
-consolelog
将 Eclipse 平台的错误日志镜像到用来运行 Eclipse 的控制台。与 -debug 组合时很方便使用。 1.0
-data workspacePath
要运行 Eclipse 平台的工作区的路径。工作区位置也是项目的缺省位置。相对于从中启动 eclipse 的目录来解释相对路径。 1.0
-debug [optionsFile]
将平台置于调试方式,并从给定位置处的文件装入调试选项(如果指定的话)。此文件指示哪些调试点可用于插件以及是否已启用它们。如果未给出文件位置,则平台在启动 eclipse 的目录中查找称为".options"的文件。URL 和文件系统路径都可作为文件位置。 1.0
-dev [classpathEntries]
将平台置于开发方式。将可选类路径条目(用逗号分隔的列表)添加至每个插件的运行时类路径。例如,当工作区包含要开发的插件时,指定 -dev bin 会为每个插件项目的名为 bin 的目录添加类路径条目,允许在其中存储最新生成的类文件。除去了冗余或不存在的类路径条目。 1.0
-endsplash params
用于在 Eclipse 平台启动并运行时关闭闪屏的内部选项。此选项在闪屏处理链中不同的位置有不同的语法和语义。 2.0
-feature featureId
主要功能部件的标识。主要功能部件为 Eclipse 的已启动实例提供了产品个性,并确定使用的产品定制信息。 2.0
-keyring keyringFilePath
磁盘上授权数据库(或"密钥环"文件)的位置。此自变量必须与 -password 选项配合使用。相对于从中启动 eclipse 的目录来解释相对路径。 1.0
-nl locale
定义 Eclipse 平台在其上运行的语言环境的名称。Eclipse 平台通常自动计算最佳设置。如果在此处指定该项,则这是 Eclipse 平台使用的值。此处指定的值可作为 BootLoader.getNL() 用于插件。示例值有:"en_US"和"fr_FR_EURO"。 2.0
-nolazyregistrycacheloading
取消激活装入优化的平台插件注册表高速缓存。缺省情况下,仅当需要时才从注册表高速缓存(可用时)中装入扩展的配置元素,以减少内存占用。此选项将在启动时强制完全装入注册表高速缓存。 2.1
-noregistrycache
绕过读写内部插件注册表高速缓存文件。 2.0
-nosplash
运行平台而不显示闪屏。 1.0
-os operatingSystem
定义 Eclipse 平台在其上运行的操作系统。Eclipse 平台通常使用 Java os.name 属性的常用值来计算最佳设置。如果在此处指定该项,则这是 Eclipse 平台使用的值。此处指定的值可作为 BootLoader.getOS() 用于插件,并用于解析插件清单文件中提及的路径中 $os$ 变量的出现。示例值有:"win32"、"linux"、"hpux"、"solaris"和"aix"。 1.0
-password password
授权数据库的密码。与 -keyring 选项配合使用。 1.0
-perspective perspectiveId
启动时要在活动工作台窗口中打开的透视图。如果没有指定该参数,则将打开关闭时活动的透视图。 1.0
-plugincustomization propertiesFile
包含插件首选项缺省设置的属性文件的位置。这些缺省设置覆盖在主要功能部件中指定的缺省设置。相对于从中启动 eclipse 的目录来解释相对路径。 2.0
-plugins pluginsFileURL
(建议不使用;用 -configuration 代替;支持 1.0 兼容)。 指定 Eclipse 平台查找插件的文件的位置,表示为 URL。该文件为属性文件格式,其中键是任意用户定义名称,值是指向 plugin.xml 文件的显式路径或指向包含插件的目录的路径的用逗号分隔的列表。注意,不允许使用相对 URL。如果指定此项,则此选项会导致创建适当的临时配置。 *1.0
-refresh
启动时执行工作区的全局刷新的选项。这将使从上次平台运行以来在文件系统中所做的任何更改一致。 1.0
-showlocation
用于在窗口标题栏中显示工作区的位置的选项。在发行版 2.0 中,此选项仅与 -data 命令行自变量一起使用。 2.0
-showsplash params
用于显示闪屏(由可执行的 Eclipse 平台启动器执行)的内部选项。此选项在闪屏处理链中不同的位置有不同的语法和语义。 2.0
-vm vmPath
要用来运行 Eclipse 平台的"Java 运行时环境"(JRE)的位置。如果不指定此项,则 JRE 位于 jre(它是 Eclipse 可执行文件的兄弟目录)。相对于从中启动 eclipse 的目录来解释相对路径。 1.0
-ws windowSystem
定义 Eclipse 平台在其上运行的 Windows 系统。Eclipse 平台通常使用 Java os.name 属性的常用值来计算最佳设置。如果在此处指定该项,则这是 Eclipse 平台使用的值。此处指定的值可作为 BootLoader.getWS() 用于插件、用于配置 SWT 以及用于解析插件清单文件中提及的路径中 $ws$ 变量的出现。示例值有:"win32"、"motif"和"gtk"。 1.0
将 -vmargs 条目后面的所有自变量(但不包括 -vmargs)作为虚拟机自变量(即,在要运行的类的前面)直接传递到所指示的 Java VM。注意:如果 Eclipse 启动在 Java vm 自变量(-vmargs)之后提供的自变量(例如,-data),则 Eclipse 将不会启动并且您将接收到"JVM 已终止。出口代码为 1"的错误。
在不同的 VM 上运行
在 J9 上运行 Eclipse
当在 J9 版本 1.5 上运行 Eclipse 时,建议使用以下 VM 选项:
eclipse.exe [eclipse arguments] -vm path_to_j9w.exe -vmargs -ms:32 -mm:2048 -mo:32768 -moi:32768 -mca:32 -mco:128 -mx:2000000
当在 J9 版本 2.0 上运行 Eclipse 时,J9W 选择的缺省自变量应为合适的选项。但是,要覆盖 Eclipse 可执行文件以内部方式自动设置的参数,必须指定 -vmargs 不带任何参数,如下所示:
eclipse.exe [eclipse arguments] -vm path_to_j9w.exe -vmargs
有关进一步信息,参考 J9 VM 文档和帮助。
在 IBM Developer Kit, Java(TM) Technology Edition VM 上运行 Eclipse
IBM Developer Kit, Java(TM) Technology Edition 1.3 Linux 的缺省 VM 设置适合进行初期研究工作,但在进行大型开发时是不够的。对于大型开发,应修改 VM 自变量以使有更多的堆可用。例如,下列设置将允许 Java 堆增大为 256MB:
posted @
2005-08-22 10:49 Dave 阅读(209) |
评论 (0) |
编辑 收藏
爱因斯坦曾经说:“任何事情都应该越简单越好,而不是比较简单。”实际上,科学真理的目的就是在假设的前提下去简化一个理论,这样,人们可以去关注真正重要的问题。在企业软件开发中,道理是一样的。
简化企业软件开发的一个关键是,提供一个这样的应用框架:它可以使开发人员不用关注于很多复杂的问题,比如事务处理、安全和持久化等。一个设计良好的框架将提升代码的可复用性,提高开发者的效率,并得到更高质量的软件。然而,目前J2EE 1.4下的EJB 2.1 框架被广泛认为是设计较差而且过度复杂的。不满足于EJB2.1框架,JAVA开发者使用了很多其他的中间件服务产品。最值得关注的是,以下两个框架吸引了大量开发者的兴趣和积极反馈。这两个框架很可能成为未来企业JAVA应用开发框架的选择。
Spring框架是一个广受欢迎的但是非标准的开源框架。它主要由Interface21公司开发和控制。Spring框架的体系结构是基于注射依赖(DI)模式。Spring框架使用了大量的XML配置文件,它可以独立应用,或者在现有的应用服务器上工作。
EJB 3.0框架是JCP定义的并且被所有主流J2EE提供商支持的标准框架。EJB 3.0规范的预发布版本目前已经有开源的和商业的实现,如JBOSS和ORACLE。EJB 3.0大量使用了JAVA注解(Java annotations,是JDK1.5提供的新功能。译者注)
这两个框架有着一个共同的核心设计理念:它们的目标是为松耦合的POJO类提供中间件服务。框架通过在运行时截取执行环境,或将服务对象注射给POJO类的方式,将应用服务和POJO类“连接”起来。POJO类本身并不关注如何“连接”,而且也很少依赖于框架。这样,开发者可以将注意力集中在业务逻辑上,可以对他们的POJO类进行与框架无关的单元测试。并且,由于POJO类不需要继承框架的类或实现框架提供的接口,开发者可以在更加灵活性的基础上构建继承体系,和搭建应用。
尽管有着共同的理念,但这两个框架采取了不同的方式来提供POJO服务。由于已经出版了大量的比较Spring与EJB2.1或者EJB3.0与EJB2.1的书籍和文章,而没有关于比较Spring和EJB3.0的认真研究,因此,本文将考察它们之间几个关键的不同,讨论他们优缺点。本文谈到的主题同样适用于其他不太有名的但同样提供“松耦合POJO” 设计的企业中间件框架。我希望,这篇文章可以帮助你选者最合适的你需求的框架。
提供商无关性
开发者选择JAVA平台的一个最重要的原因就是它的提供厂商无关性。EJB 3.0是一个被设计为对提供商没有依赖性的开放的标准。EJB 3.0规范由企业JAVA社区的主流开源组织和厂商共同编写和支持的。EJB 3.0框架使开发者的应用程序实现可以独立于应用服务器。比如,JBoss的EJB 3.0的实现是基于Hibernate的,Oracle的EJB 3.0实现是基于TopLink的,但是,在JBoss或者Oracle上跑应用程序,开发者既不需要去学习Hibernate,也不需要学习TopLink提供的独特API。厂商无关性使EJB 3.0框架区别于当前其他任何的POJO中间件框架。
然而,就象很多EJB 3.0的批评者很快指出的一样,目前EJB 3.0规范正在编写还未完全完成最终发布版。很有可能,还需要1至2年,EJB 3.0才会被主流J2EE厂商完全接受。但是,就算你的应用服务器本身不支持EJB 3.0,你也可以通过下载和安装一个“可嵌入的” EJB 3.0产品,来使你的应用服务器支持EJB 3.0应用。比如,JBoss“可嵌入的” EJB 3.0产品是开源的,它可以运行在任何兼容J2SE-5.0环境下(如你的应用服务器),目前处于Beta版测试中。其他厂商同样可以快速发布他们自己的可嵌入EJB 3.0产品,特别是规范中“数据持久化”部分。
另一方面,Spring一直是一个非标准的技术,而且在可以预计的未来仍将如此。尽管你在任何应用服务器都上可以使用Spring框架,但基于Spring的应用仍然被限制于Spring本身和在你的应用中使用到的Spring提供的各种特别服务。
由于Spring框架是一个开源项目,因此,它使用的配置文件XML格式和开发接口都是私有的。当然,这种限制不仅体现在Spring框架中,其他任何非标准产品都会有这种限制。但是,你的Spring应用的长期生存能力将依赖于Spring项目本身(或者说Interface 21公司,因为它雇佣了大多数的Spring核心开发人员)。并且,如果你使用了Spring提供的特殊服务,如Spring事务管理器或者Spring MVC,你同样被限制于Spring提供的API。
并且,Spring应用是知道后端服务提供者的(即应用程序是知道服务提供者的,这样应用程序将会在一定程度上依赖于服务提供方:译者注)。例如,对于数据持久化服务,Spring框架提供了不同的DAO和模板Helper类,用于JDBC、Hibernate,、iBatis和JDO。这样,假如你需要改变一个Spring应用的持久化服务提供者(如,从JDBC换到Hibernate),你将需要重构你的系统应用代码,来使用新的Helper类。
服务整合 Spring框架是建立在应用服务器和服务库之上,它的服务整合代码(如数据访问模板和Helper类)是基于框架的,并暴露给应用开发者。相反,EJB 3.0框架是紧密整合到应用服务器中的,它的服务整合代码是封装在一个标准的接口下的。
因此,EJB 3.0厂商可以轻松的优化整体性能和开发者体验。如,在JBoss的EJB 3.0实现中,当你通过实体管理器持久化一个实体BEAN POJO时,Hibernate session事务将在JTA事务提交时自动提交。通过使用简单的@PersistenceContext注解(例子参看后面文章),你可以甚至可以将实体管理器和其下的Hibernate事务绑定到一个有状态的session bean上。应用程序事务可以在一个session中跨越多个线程,在事务性的WEB应用中这是非常有用的,如多页面的购物车。
基于EJB 3.0 框架、Hibernate、和JBoss 内部Tomcat的紧密整合,上面提到的简单的整合的编程接口是可能的。Oracle的EJB 3.0框架和它内部的Toplink持久服务可以达到同样层次的整合。
EJB 3.0中整合服务的另一个好例子是集群支持。假如你部署一个EJB 3.0应用到一个集群服务器,所有的故障切换、负载均衡、分布式缓存、和状态复制服务对于应用程序来说,都是自动完成的。集群服务被隐藏在EJB 3.0编程接口之下,对于EJB 3.0开发者来说,这些服务都是完全透明的。
在Spring中,优化框架和服务之间交互更加困难一些。例如,想要用Spring的声明式事务服务来管理Hibernate事务,必须在XML配置文件中明确的配置Spring的事务管理器(TransactionManager)和Hibernate SessionFactory对象。Spring应用开发者必须自己管理跨越多个HTTP请求的事务。并且,没有简单的方法可以在Spring应用中实现集群服务
服务聚合的灵活性 由于Spring中的服务整合代码是作为编程接口暴露给应用开发者的,因此开发人员可以根据需要来聚合多个服务。这个特性使你可以集成一个你自己的“轻量”级应用服务器。Spring的一个通常的用法是将Tomcat和Hibernate连接起来来支持简单的数据库驱动的WEB应用程序。在这种情况下,Spring本身提供了事务管理服务,Hibernate提供了持久化服务,这种设置本身就创建了一个小型的应用服务器。
通常,EJB 3.0应用服务器不提供给开发者这种按照你的需要来选择服务的灵活性。大多数情况,你会得到一系列已经预先打包好的特性,其中有些你可能是不需要的。然而,如果应用服务器提供了模块内部的独特设计,就象JBOSS一样,你可以不去关心这些不必要的特性。在任何情况下,去定制一个全功能的应用服务器并不是一个琐碎而没有意义的工作。
当然,如果一个应用不是一个单一的结点,你将需要连接多个应用服务器提供的服务(如资源池、消息队列和集群)。这种情况下,从总的资源消耗上看,Spring框架就和任何EJB 3.0方案一样是“重量级”的。
为了进行容器外的单元测试,Spring的灵活的服务聚合也可以来连接假对象,来替代真的服务对象。在EJB 3.0应用中,大多数的组件都是简单POJO,他们可以容易进行容器外的单元测试。但是,如果要测试与容器服务相关的服务对象(如持久化实体管理器),更好的方式是进行容器内的测试,因为这样比使用假对象来替代的方式更加容易,更加健壮,而且更加准确。
XML vs. 注解
从应用开发者的角度来看,Spring的编程接口主要基于XML配置文件,而EJB 3.0则大量的使用了JAVA注解。XML文件可以表达复杂的关系,但是它们更加冗长而且不健壮。注解的方式很简单明了,但是很难去表达复杂的或者继承性的结构。
Spring和EJB 3.0分别选择了XML和注解方式,这取决于框架的体系结构:由于注释只能描述相当少的配置信息,只有一个预先整合好的框架(如大多数重要事情已经在框架中实现了)才能大量的使用注释作为它的配置选项。象我们讨论的一样,EJB 3.0满足了这些要求,而Spring作为一个一般的注射依赖框架,它没有做到这一点。
当然,由于EJB 3.0和Spring相互学习了很多特性,所以,它们都在某种层次上支持XML和注释。例如,EJB 3.0中可以应用XML配置文件来作为一个选择性的机制,用来改变注释的默认行为。注释也可以用来配置一些Spring服务。
研究XML和注释直接区别的最好的方式就是通过例子。在下面的几节中,我们将一起看一下EJB 3.0和Spring是如何为应用程序提供关键服务的。
声明式服务 EJB 3.0和Spring都将运行时服务(如事务管理、安全、日志、消息、和信息服务)连接给应用程序。由于这些服务同应用程序的业务逻辑并不是直接相关的,因此,它们不被应用程序本身来管理。相反,这些服务被服务容器(如EJB 3.0和Spring)以不可见的方式在运行时提供给应用程序。开发人员(或系统管理员)通过配置来告诉容器什么时候,以怎样的方式来应用这些服务。
EJB 3.0通过JAVA注解的方式来配置声明式服务,Spring则通过XML配置文件来完成。大多数情况下,EJB 3.0 的注解方式是应用这种服务的更加简单和优美的方式。下面是一个在EJB 3.0中对一个POJO的方法使用事务管理服务的例子。
public class Foo {
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public bar () {
// do something ...
}
}
你可以对一段代码声明多个属性,并应用多个服务。下面是一个对EJB 3.0中POJO类同时使用事务管理服务和安全服务的例子。
@SecurityDomain("other")
public class Foo {
@RolesAllowed({"managers"})
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public bar () {
// do something ...
}
}
使用XML指定代码属性和配置声明服务将导致冗长的和不桅顶的配置文件。下面是Spring应用中一个XML元素的例子,它用来在Foo.bar()方法上应用一个非常简单的Hibernate事务。
<!-- Setup the transaction interceptor -->
<bean id="foo"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="target">
<bean class="Foo"/>
</property>
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="transactionAttributeSource">
<ref bean="attributeSource"/>
</property>
</bean>
<!-- Setup the transaction manager for Hibernate -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory">
<!-- you need to setup the sessionFactory bean in yet another XML element -->
<ref bean="sessionFactory"/>
</property>
</bean>
<!-- Specify which methods to apply transaction -->
<bean id="transactionAttributeSource"
class="org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource">
<property name="properties">
<props>
<prop key="bar">
</props>
</property>
</bean>
XML文件的复杂程度将随着你对同一个POJO类增加的拦截器的数量程几何增长。意识到了仅使用XML配置文件的限制性,Spring支持在JAVA源代码中使用Apache Commons metadata来指定事物属性。在最新的Spring 1.2中,JDK-1.5风格的注释也被支持。为了使用事务元数据,你需要为上面例子中的AttributesTransactionAttributeSource 改变一个transactionAttributeSource bean,并且增加一个附加的对元数据拦截器的设置。
<bean id="autoproxy"
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
<bean id="transactionAttributeSource"
class="org.springframework.transaction.interceptor.AttributesTransactionAttributeSource"
autowire="constructor"/>
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor"
autowire="byType"/>
<bean id="transactionAdvisor"
class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor"
autowire="constructor"/>
<bean id="attributes"
class="org.springframework.metadata.commons.CommonsAttributes"/>
当你有许多事务方法时,Spring元数据简化了transactionAttributeSource元素。但是它没有解决XML配置文件的根本问题:仍然需要冗长的、易错的事务拦截器,事务管理器,和事务属性。
注射依赖
中间件容器的一个主要优点是它们使得程序开发人员可以去构建松耦合的应用程序。服务使用者仅仅需要知道服务接口就可以使用服务。容器把具体的服务实现实例化,然后将它们提供给服务使用者。这样,容器可以在可替换的服务实现之间进行切换,而不改变服务接口和服务使用者代码。
注射依赖模式是实现松耦合应用程序的一个最好的方式。比起以前的方式,如通过JNDI进行查找或回调容器,注射依赖模式更容易使用,而且更加优美。使用注射依赖模式,框架扮演了构建服务的对象工厂角色,然后根据运行时的配置,把这些服务对象注射到应用程序的POJO类中。从程序开发人员的角度看,作为客户端使用者的POJO在需要使用服务对象前就自动的得到了它们。
Spring 和 EJB 3.0都提供了大量的DI模式支持。但是,它们之间也有着根本的不同。Spring支持了通常意义上的但是复杂的基于XML配置文件的注射依赖API;EJB 3.0支持的注射大多数通用服务对象(如,EJB和容器对象)和JNDI对象,它通过简单的JAVA注解来完成。
EJB 3.0的注射注解相当的简洁易用。@Resource标签注射大多数的通过服务对象和JNDI对象。下面的例子显示了如何将JNDI提供的服务器缺剩数据源对象注射给一个POJO的一个字段。DefaultDS是这个数据源的JNDI名字。myDb 变量在第一次被使用前就自动被赋予了正确的值。
public class FooDao {
@Resource (name="DefaultDS")
DataSource myDb;
// Use myDb to get JDBC connection to the database
}
在EJB 3.0中,注释@Resource不仅可以直接注射给属性变量,它也可以通过setter方法来完成注射。下面的例子将一个session上下文对象通过setter方法注射给使用者。应用程序不用显示的调用setter方法,在任何其他方法被调用前容器将调用setter方法完成注射。
@Resource
public void setSessionContext (SessionContext ctx) {
sessionCtx = ctx;
}
对于更复杂的服务对象,还有一些特殊的注射注解。例如,@EJB 注解被用来注射EJB stubs,@PersistenceContext注解被用来注射实体管理器对象,这些对象负责处理EJB 3.0实体Bean的数据访问操作。 下面的例子给出如何将一个实体管理器注射到一个有状态Session Bean中。@PersistenceContext注解的类型属性描述了被注射的的实体管理器有一个扩展的事务容器:它不会随着JTA事务管理器自动提交事务,因此它可以应用在当session中有多次操作的应用事务管理时。
@Stateful
public class FooBean implements Foo, Serializable {
@PersistenceContext(
type=PersistenceContextType.EXTENDED
)
protected EntityManager em;
public Foo getFoo (Integer id) {
return (Foo) em.find(Foo.class, id);
}
}
EJB 3.0 规范定义了可以通过注解来被注射使用的服务器资源。但是,它不支持用户自定义的POJO类之间的相互注射。
在Spring中,为了将服务对象注射到你的POJO类中,你首先需要定义一个setter方法(或有参数的构造函数) 。下面的例子演示了 POJO 类中一个Hibernate session 工厂的属性。
public class FooDao {
HibernateTemplate hibernateTemplate;
public void setHibernateTemplate (HibernateTemplate ht) {
hibernateTemplate = ht;
}
// Use hibernateTemplate to access data via Hibernate
public Foo getFoo (Integer id) {
return (Foo) hibernateTemplate.load (Foo.class, id);
}
}
因此,你可以指定容器如何得到这个服务,并且在运行时通过配置文件中XML元素的连接关系把它提供给POJO。下面的例子显示了连接一个数据源到一个Hibernate session 工厂、session 工厂到Hibernate模板对象、模板对象最后到应用程序POJO类,整个过程的XML配置。
Spring 代码复杂性的部分原因是,我们需要手工的去注射Hibernate相关类,然而,EJB 3.0 实体管理器被服务器自动管理和配置。但是,这使我们返回到了这样的讨论:Spring 不象EJB 3.0 一样,它不同服务紧密整合在一起。
<bean id="dataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiname">
<value>java:comp/env/jdbc/MyDataSource</value>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<bean id="hibernateTemplate"
class="org.springframework.orm.hibernate.HibernateTemplate">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<bean id="fooDao" class="FooDao">
<property name="hibernateTemplate">
<ref bean="hibernateTemplate"/>
</property>
</bean>
<!-- The hibernateTemplate can be injected into more DAO objects -->
尽管Spring中基于XML的注射依赖比较复杂,但是它非常强大。你可以注射任何POJO到另外的POJO中,包括程序中自定义的。
如果你确实想在EJB 3.0应用中使用Spring的注射依赖功能,你可以将一个Spring Bean工厂类通过JNDI注射到一个EJB中。在某些EJB 3.0 应用服务器中,厂商可能会定义一些非标准的API用来注射任意的POJO类。一个很好的例子是JBoss MicroContainer,它处理了AOP依赖性,因此它是甚至比Spring 更加通用。
结论
尽管Spring 和EJB 3.0的目标都是提供企业服务,使得POJO可以松耦合,但是它们实现的方式非常不同。在两个框架中注射依赖模式都有大量的应用。
通过EJB 3.0的标准方式、大量应用的注解、还有同应用服务器紧密整合性,这些提供了更高的厂商无关性和开发人员工作效率。Spring的以XML为中心的配置文件和注射依赖的连贯使用,允许开发人员去构造更加灵活的应用系统,并且可以同时与多个应用服务提供者同时工作。
感谢
作者感谢Stephen Chambers, Bill Burke, 和Andy Oliver 的有价值的评论.
参考
The Spring framework (参考CodeZoo: Spring)
EJB 3.0
JBoss EJB 3.0
Oracle Application Server EJB 3.0 Preview
Michael Juntao Yuan specializes in end-to-end enterprise solutions and is a mobile geek and avid open source supporter.
posted @
2005-08-22 10:13 Dave 阅读(226) |
评论 (0) |
编辑 收藏
bsh-deployer:将BeanShell脚本部署成JBoss服务。
cache-invalidation-service.xml:允许借助于JMS,而实现对EJB缓存的控制。
client-deployer-service.xml:部署J2EE应用客户。
ear-deployer.xml:部署J2EE EAR应用。
ejb-deployer.xml:部署J2EE EJB应用。
hsqldb-ds.xml:设置嵌入式Hypersonic数据库服务,并将其作为默认数据源。
http-invoker.sar:通过RMI/HTTP方式访问到MBean和EJB。
jboss-aop.deployer:提供AspectManagerService,并部署JBoss AOP应用。
jboss-hibernate.deployer:部署Hibernate存档(HAR文件)。
jboss-local-jdbc.rar和jboss-xa-jdbc.rar:集成JDBC驱动的JCA资源适配器,它们分别支持DataSource和XADataSource。但是,这并没有提供专有JCA实现。
jboss-ws4ee.sar:提供J2EE Web服务支持。
jbossjca-service.xml:JBoss JCA实现,使得在JBoss中部署JCA资源适配器成为可能。
jbossweb-tomcat50-sar:含有嵌入式Tomcat服务的展开SAR文件。它为JBoss提供了标准的Web容器。
jms:将JMS相关的服务聚集在一起,并放置在jms目录中。
hsqldb-jdbc-state-service.xml:使用HSQLDB管理状态。
hsqldb-jdbc2-service.xml:使用嵌入式HSQL数据库实现缓存和持久化。它还包含了JMS实现的核心服务,即DestinationManager MBean。
jbossmq-destinations-service.xml:供JBoss测试套件使用的JMS Topic和Queue。
jbossmq-service.xml:JMS其他服务,包括拦截器配置。
jms-ds.xml:将JBoss消息实现作为默认JMS提供商。并且,它还提供JCA配置信息,以供集成JBoss JCA和JMS资源适配器使用。
jms-ra.rar:资源适配器,供JCA处理JMS连接工厂使用。
jbossmq-httpil.sar:提供JMS调用层,从而实现HTTP方式使用JMS。
jvm-il-service.xml:配置本地JMS传输调用层,供本地JVM使用JMS。
uil2-service.xml:配置JMS版本2统一调用层。这是一种可靠的、自定义的、基于Socket的传输方式。推荐在不同JVM间使用它。
jmx-console.war:JMX控制台应用。前面讨论过。
jmx-invoker-server.xml:为远程访问JMX MBean服务器提供支持。
mail-ra.rar:为JavaMail提供资源适配器。
mail-service.xml:允许应用和服务在JBoss中使用JavaMail。请注意,邮件服务器相关信息必须由用户提供。
management:含有可更换管理服务的子目录。其中,包含有改进的Web控制台。
monitoring-service.xml:配置警告监听器,比如控制台监听器、E_mail监听器,等等。
properties-service.xml:设置JVM的全局系统属性(由System.getProperties返回)。
schedule-manager-service.xml和scheduler-service.xml:定时任务服务。
sqlexception-service.xml:为JDBC驱动提供标识一般性SQL异常。
uuid-key-generator.sar:生成唯一的、基于UUID的键。
all配置提供了其他配置没有提供的其他服务,用户可以将这些服务集成到各自的服务器配置中。具体如下:
cluster-service.xml:群集服务,包括JGroups集成服务、HA-JNDI、有状态会话Bean复制、CMP2缓存有效性服务。
deploy-hasingleton-service.xml:HASingletonDeployer MBean。用于确保群集中只有单个节点在deploy-hasingleton目录部署了服务。
deploy.last/farm-service.xml:farm群集部署服务。用于确保它在所有其他服务部署之后才部署其本身。
ebxmlrr-service.xml:JAXR注册服务实现。
iiop-service.xml:实现对CORBA、IIOP的支持。
jbossha-httpsession.sar:遗留的HTTP会话复制服务。
remoting-service.xml:还处于试验中的下一代分离式Invoker框架。
snmp-adaptor.sar:将JMX通知转换成SNMP陷阱。
tc5-cluster-service.xml:用于新的HTTP复制服务的TressCache配置。
posted @
2005-08-22 09:25 Dave 阅读(1206) |
评论 (1) |
编辑 收藏
目录结构:
bin:含有启动、停止以及其他系统相关脚本。在前面,本书已经讨论过启动JBoss应用服务器的run脚本。
client:存储供Java客户应用或者外部Web容器使用的配置文件和JAR文件。用户可以使用所需要的具体存档,或者仅仅使用jbossall-client.jar。
docs:含有JBoss引用的XML DTD文件(当然,还包括JBoss具体配置文件)。同时,还存在JCA(Java Connetor Architecture,Java连接器架构)实例配置文件,供设置不同数据库的数据源使用(比如MySQL、Oracle、Postgres)。
lib:包含运行JBoss微内核所需的JAR文件。请注意,不要往该目录添加用户自身的任何JAR文件。
server:包含的各个子目录都是不同的服务器配置。通过往run脚本后添加-c <config name>参数便能够指定不同的配置。接下来,来看看default服务器配置。
从根本上考虑,JBoss架构是由JMX MBean服务器、微内核、一套可插入式组件服务以及MBean构成的。这种架构使得,集成不同的配置变得更加简单,并且能够很灵活地满足用户的各自需求。用户不再需要一次性运行重量级的应用服务器。同时,用户可以删除不再需要使用的组件(这将从很大程度上减少服务器的启动时间),并且通过开发自己的MBean还能够集成其他服务到JBoss中。当然,如果是运行标准J2EE应用,则不用理会这些自定义工作。用户所需要的一切服务,JBoss发布版都包括了。
server目录下存在3个服务器实例配置:all、default以及minimal,它们各自提供了不同的服务集合。很显然,如果启动JBoss服务器时没有指定其他配置,则将使用default配置。
minimal:这是启动JBoss服务器所要求的最低配置。minimal配置将启动日志服务、JNDI服务器以及URL部署扫描器,以找到新的部署应用。对于那些不需要使用任何其他J2EE技术,而只是使用自定义服务的场合而言,则这种JMX/JBoss配置最适合。它仅仅是服务器,而不包含Web容器、不提供EJB和JMS支持。
default:默认配置,它含有大部分J2EE应用所需的标准服务。但是,它不含有JAXR服务、IIOP服务、或者其他任何群集服务。
all:提供了所有可用的服务。它包含RMI/IIOP和群集服务,default配置中没有提供群集服务。
用户也可以添加自身的服务器配置。最佳做法是,拷贝最接近用户需求的现有配置,然后修改其具体内容。比如,如果用户不需要使用消息服务,则只需要拷贝default目录,并重新命名为myconfig,然后删除jms子目录。最后,启动myconfig配置。
run -c myconfig
default服务器配置目录的具体内容:
conf:含有指定JBoss核心服务的jboss-service.xml文件。同时,还包括核心服务的其他配置文件。
data:Hypersonic数据库实例将数据存储在此处。JBossMQ(JMS的JBoss实现)也使用它存储消息。
deploy:用户将应用代码(JAR\WAR\EAR文件)部署在此处。同时,deploy目录也用于热部署服务(即,那些能够从运行服务器动态添加或删除的服务)和部署JCA资源适配器。因此,用户能够在deploy目录看到大量的配置文件。尤其是,用户能够看到JMX控制台应用(未打包的WAR文件),本书前面讨论过。JBoss服务器将定期扫描该目录,从而查找是否有组件更新或修改,从而自动完成组件的重新部署。本书后续章节将详细阐述部署细节。
lib:服务器配置所需的JAR文件。用户可以添加自身的库文件,比如JDBC驱动,等等。
log:日志信息将存储到该目录。JBoss使用Jakarta Log4j包作为其日志功能。同时,用户可以在应用中直接使用Log4j日志记录功能。
tmp:供部署器临时存储未打包应用使用,也可以作为其他用途。
work:供Tomcat编译JSP使用。
其中,data、log、tmp、work目录是JBoss创建的。如果用户没有启动过JBoss服务器,则这些目录不会被创建。
.
2.2.1 核心服务
当JBoss服务器启动时,首先会启动conf/jboss-service.xml文件指定的核心服务。
虽然通过conf/jboss-service.xml文件能够添加其他MBean服务,但是更好的办法是,将单独的配置文件放置在deploy目录中,因为这将使得用户的服务具有热部署能力。
2.2.2 日志服务
Log4j是JBoss使用的日志功能包。通过conf/log4j.xml文件能够控制JBoss的日志功能。
2.2.3 安全性服务
安全性域信息存储在login-config.xml文件中,其包含了许多安全性域定义。各个安全性域指定了许多JAAS登陆模块,供安全性域认证使用。当用户需要在应用中使用安全性时,需要在JBoss特定部署描述符jboss.xml或jboss-web.xml中指定待使用的安全性域名。
2.2.4 其他服务
deploy目录放置的服务不是核心服务,但具有热部署能力。用户可以通过XML描述符文件(*-service.xml)或JBoss服务存档(SAR)文件给出服务。SAR同时含有XML描述符和服务所要求的其他资源(比如,类、JAR库文件以及其他存档),而且SAR是以单个存档文件给出的。
posted @
2005-08-19 17:47 Dave 阅读(889) |
评论 (2) |
编辑 收藏
投资是一种追求未来货币增值的经济行为。
新中国的第一张股票:1984年12月发行的上海飞乐音响公司的股票。
90年12月19日,上证交易所开业
posted @
2005-08-19 15:36 Dave 阅读(155) |
评论 (0) |
编辑 收藏
Unlike ad hoc non-EJB architectures, it is similar to EJB architectures in being centered around a layer of managed business service objects. However, this is where the similarity ends. Instead of running inside an EJB container, business objects run inside a lightweight container. A lightweight container isn't tied to J2EE, so it can run in a web container, a stand-alone application, or even an EJB container if necessary. It also isn't tied to the Servlet API, like an MVC web framework, which is a poor choice for managing business objects. Lightweight containers have negligible startup cost and eliminate the deployment step of EJB.
Lightweight containers provide a way to manage and locate business objects. No longer is there any need for JNDI lookups, custom service locators, or Singletons: the lightweight container provides a registry of application objects.
Lightweight containers are both less invasive and more powerful than an EJB container where co-located applications are concerned.
To provide a complete solution, the lightweight container must provide enterprise services such as transaction management. Typically this will invoke AOP interception: transparently weaving in additional behavior, such as transaction management, before and after the execution of business methods.
From the user’s perspective, the web tier is provided by an MVC framework. We can use a dedicated
web framework such as Struts or WebWork, or—in the case of Spring—a web tier that can itself be managed
by the lightweight container and provide close integration with business objects.
Business objects will be POJOs, running inside the lightweight container. They may be “advised” via AOP interception to deliver enterprise services. Unlike EJBs, they don't usually need to depend on container
APIs, meaning that they are also usable outside any container. Business objects should be accessed
exclusively through their interfaces, allowing pluggability of business objects without changing calling
code.
Data access will use a lightweight O/R mapping layer providing transparent persistence, or JDBC via a
simplifying abstraction layer if O/R mapping adds little value.
StrengthsFollowing are some of the advantages of using this architecture:
(1) A simple but powerful architecture.
(2) As with local EJBs or an ad hoc non-EJB solution, horizontal scalability can be achieved by clustering
web containers. The limitations to scalability, as with EJB, will be session state management,
if required, and the underlying database. (However, databases such as Oracle 9i RAC can
deliver huge horizontal scalability independent on the J2EE tier.)
(3) Compared to an ad hoc non-EJB architecture, using a lightweight container reduces rather than
increases complexity. We don't need to write any container-specific code; cumbersome lookup
code is eliminated. Yet lightweight containers are easier to learn and configure than an EJB
container.
(4) Sophisticated declarative services can be provided by a lightweight container with an AOP
capability. For example, Spring's declarative transaction management is more configurable than
EJB CMT.
(5) This architecture doesn't require an EJB container. With the Spring Framework, for example,
you can enjoy enterprise services such as declarative transaction management even in a basic
servlet engine. (Whether you need an application server normally depends on whether you
need distributed transactions, and hence, JTA.)
(6) Highly portable between application servers.
(7) Inversion of Control allows the lightweight container to “wire up” objects, meaning that the complexity
of resource and collaborator lookup is removed from application code, and application
objects don't need to depend on container APIs. Objects express their dependencies on collaborators
through ordinary Java JavaBean properties or constructor arguments, leaving the IoC
container to resolve them at runtime, eliminating any need for tedious-to-implement and hardto-
test lookups in application code.IoC provides excellent ability to manage fine-grained business objects.
(8) Business objects are easy to unit test outside an application server, and some integration testing
may even be possible by running the lightweight container from JUnit tests. This makes it easy
to practice test first development.
WeaknessesFollowing are some of the disadvantages of using this architecture:
(1) Like a local EJB architecture, this architecture can't support remote clients without an additional
remoting facade. However, as with the local EJB architecture, this is easy enough to add, especially
if we use web services remoting (which is becoming more and more important). Only in
the case of RMI/IIOP remoting are remote EJBs preferable.
(2) There's currently no “standard” for lightweight containers comparable to the EJB specification.
However, as application objects are far less dependent on a lightweight container than EJBs are
on the EJB API, this isn't a major problem. Because application objects are plain Java objects,
with no API dependencies, lock-in to a particular framework is unlikely. There are no special
requirements on application code to standardize.
(3) This architecture is currently less familiar to developers than EJB architectures. This is a nontechnical
issue that can hamper its adoption. However, this is changing rapidly.
Implementation IssuesFollowing are some of the implementation issues you might encounter:
(1) Declarative enterprise services can be provided by POJOs using AOP, thus taking one of the best
features of EJB and applying it without most of the complexity of EJB.
(2) A good lightweight container such as Spring can provide the ability to scale down as well as up.
For example, Spring can provide declarative transaction management for a single database
using JDBC connections, without the use of JTA. Yet the same code can run unchanged in a different
Spring configuration taking advantage of JTA if necessary.
(3) A nice variation is ensuring that POJO business objects can be replaced by local EJBs without
changes in calling code. Spring provides this ability: all we need to do is create a local EJB with
a component interface that extends the business interface, if we wish to use EJB. These last two
points make this approach highly flexible, if requirements change. (This results largely from
good OO programming practice and the emphasis on interfaces.)
posted @
2005-08-18 16:19 Dave 阅读(199) |
评论 (0) |
编辑 收藏
建立信任
及时给予肯定
出错时调整注意力
表现管理学ABC
A=催化剂(activator)
任何引发表现的原因
B=行为(behavior)
发生的表现
C=结果(consequence)
你对所产生表现的反应
四种结果
1.没有反应
2.表示否定
3.调整指令
4.表示肯定
调整指令的方法
●尽可能快地、清晰而不带责备地指出错误
●解释错误的负面影响
●如果可以,将过错归结于没有清楚地解释工作任务
●详细地重新解释工作任务,并确保对方已完全理解
●表达你对当事人仍然充满信任与信心
表扬进步
发现他们越做越好,即便做得不是完全正确,也要表扬他们的进步。通过这种方法,
你就将他们推上了成功之路,并使他们可以在那里继续前进
鲸鱼哲学反应
●立即表扬别人
●具体指出他们哪些做得对,哪些做得基本正确
●与他们分享你对于他们所做工作的积极感觉
●鼓励他们继续好好工作
猫捉老鼠
发现别人做的错事
鲸鱼哲学
发现别人做得正确的事情
当一切进展顺利的时候,
清醒点,
说点表示肯定的话!
无论什么时候,只要你批评了别人的行为或是给了对方一个否定的反馈,不管你多么
小心地去措辞,结果都会破坏或削弱你与他之间的关系。如果你不断地这样做,你就会彻底毁了这种关系。他们会对你失去信任并开始用同样的方法对待你。
首先,不需要被其他人激励而做事情的人只有企业家,他们要么拥有自己的生意,要么是为自己工作的自由职业者。他们是自觉的,而且他们的目标与整个组织的目标是联系在一起的。事实上,他们个人的目标通常与组织的目标是相同的。其他任何人——雇员、家里的孩子,或者是海洋世界的鲸鱼——被要求做的事情都是组织需要他们去做的事情,而且是那些如果让他们自己选择,他们可能会选择不做的事情。
即使是鲸鱼哲学反应本身也不是最终目的,它只是帮助人们实现‘发现自己做得正确的事情’这一最终目标的手段。
拥有权利是一件了不起的事情,但是不要利用它。你能够真正让人们做你想让他们做的事情的惟一途径,就是与他们建立起一种积极的、信任的关系。对人要及时肯定,这样你就会得到积极的结果。
如今,任何新的经营举措,不论是技术还是服务的革新,抑或是价格战略,都会立刻被别人知晓并被
抄袭。也就是说,你仅有的、真正可竞争的空间只是你与员工的关系。如果他们信任、尊重你,并相信你制定的目标,他们就会想方设法去取悦你的顾客。一旦你拥有了这些,再加上你的一些其他优势,比如产品质量、价格和市场营销以及送货上门等等,那就没有人能够战胜你了。你与下属的关系,以及下属与顾客之间的关系,任何竞争对手都永远无法从你这里偷走,只有这一样东西是你惟一拥有的。
规则就是,永远不要以为你知道可以激励别人的东西是什么。
鲸鱼哲学只有在你
真诚和诚实的时候才会奏效
一些“鲸鱼哲学”反应
在工作中
对管理人员:
你在会上提出的建议十分出色。你设计的开场白是为了引起人们的注意,我果然看到A女士在你说到XX的时候,神情很振奋。你在那么短的时间内所做的一切非常有助于客户对我们树立信心。你的话给我们所有人都增了光。继续好好干吧!
对一个工作团队:
咱们这个组在融洽合作与履行责任方面都非常出色。在接任本组的领导工作期间,是你们帮助我转换了
角色,让我从老板变成了协调人。我更喜欢这样的角色。希望我们这个团队继续好好工作。
对一个做出贡献的个人:
我很欣赏你在报告中自创的数字分组的方式,这样更容易看清结果。我想推荐所有人从现在开始都使用
你的方法。期待你今后想出更多的好主意。
对十几岁的儿子:
我真高兴回家看到你把车库打扫干净了。我原打算这个周六自己干这活儿,没想到你提前做了。这下我
可以放松放松,干点别的了。你让我松了口气,巴德,非常感谢你!
对一个刚上一年级的孩子:
早上我刚叫你一遍你就起床了。当时我们都在忙着收拾东西各自上路,你知道你一叫就起帮了我多少忙
吗?非常多!
对一个十二岁的女儿:
我非常喜欢在开车送你去运动和上课的路上跟你聊天。听你说你和你朋友们的事情真有趣。我希望在你
成长的过程中我们还能继续这样的交谈。
对一个学龄前儿童:
你没用别人帮忙就自己系好了鞋带、选好了要穿的衣服,真是棒极了!继续努力。我真为你感到骄傲。
一些调整指令反应
在工作中
●比尔,我知道你在使用新的结算系统时遇到了麻烦,我准备让贝蒂帮你一把。(一段时间后)干得不
错,比尔。你交上来的报告说明你在使用这套系统方面已经成了佼佼者。如果你有什么问题尽管告诉我。
●我们希望在这个项目上,每个人的才干都可以最大限度地发挥出来,埃利森。这就是我把你派到乔治
那一组去的原因。在那里,他们会用上你所有的技术。(一段时间后)祝贺你,埃利森。我早就知道你是跟乔治那一组工作的最佳人选。我非常欣赏你的工作。
在家里
(孩子没有好好喂宠物。)
我现在不让你喂宠物了,去用吸尘器打扫卫生吧。我知道你喜欢做这项家务,而且房间也确实该打扫了。(一段时间后)经过你的打扫,这房子看起来真漂亮!
(孩子们正在因为看电视而吵闹。)
为了让每个人都满意,我们需要为看电视制定一个计划。(一段时间后)我真高兴你们两个能按照那天
我们在厨房里制定的计划看电视!
posted @
2005-08-17 14:06 Dave 阅读(1310) |
评论 (2) |
编辑 收藏
Reflection combines with effective object-oriented design to allow programs to be more flexible. Delegation is useful because it allows an object to change behavior at runtime. This change in behavior happens when one delegate that provides one behavior is replaced with another delegate that provides a different behavior. The number of different delegates available defines the amount that this behavior can vary.
Without reflective mechanisms, the number of delegates is limited to only the set of classes that are included in the system at comple time. Reflection increases this range of variation by allowing the system to use classes that are written later. There are several noteworthy aspects of this relationship:
posted @
2005-08-17 10:41 Dave 阅读(89) |
评论 (0) |
编辑 收藏
public class MainApplication {
private Properties props;
private CustomerDatabase custDB;
public synchronized CustomerDatabase createDBFacade() {
if (custDB == null) {
try {
String dbClassName = props.getProperty("db.class",
"com.wci.app.StubCustomerDB");
Class cls = Class.forName(dbClassName);
custDB = (CustomerDatabase) cls.newInstance();
} catch (ClassNotFoundException ex) {
// ...
} catch (InstantiationException ex) {
// ...
} catch (IllegalAccessException ex) {
// ...
}
}
return custDB;
}
}
posted @
2005-08-17 10:11 Dave 阅读(95) |
评论 (0) |
编辑 收藏
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.IdentityHashMap;
import java.util.Map;
import org.jdom.Document;
import org.jdom.Element;
public class Driver {
public static Document serializeObject(Object source) throws Exception {
return serializeHelper(source, new Document(new Element("serialized")),
new IdentityHashMap());
}
private static Document serializeHelper(Object source, Document target,
Map table) throws Exception {
String id = Integer.toString(table.size());
table.put(source, id);
Class sourceclass = source.getClass();
Element oElt = new Element("object");
oElt.setAttribute("class", sourceclass.getName());
oElt.setAttribute("id", id);
target.getRootElement().addContent(oElt);
if (!sourceclass.isArray()) {
Field[] fields = Mopex.getInstanceVariables(sourceclass);
for (int i = 0; i < fields.length; i++) {
if (!Modifier.isPublic(fields[i].getModifiers()))
fields[i].setAccessible(true);
Element fElt = new Element("field");
fElt.setAttribute("name", fields[i].getName());
Class declClass = fields[i].getDeclaringClass();
fElt.setAttribute("declaringclass", declClass.getName());
Class fieldtype = fields[i].getType();
Object child = fields[i].get(source);
if (Modifier.isTransient(fields[i].getModifiers())) {
child = null;
}
fElt.addContent(serializeVariable(fieldtype, child, target,
table));
oElt.addContent(fElt);
}
} else {
Class componentType = sourceclass.getComponentType();
int length = Array.getLength(source);
oElt.setAttribute("length", Integer.toString(length));
for (int i = 0; i < length; i++) {
oElt.addContent(serializeVariable(componentType, Array.get(
source, i), target, table));
}
}
return target;
}
private static Element serializeVariable(Class fieldtype, Object child,
Document target, Map table) throws Exception {
if (child == null) {
return new Element("null");
} else if (!fieldtype.isPrimitive()) {
Element reference = new Element("reference");
if (table.containsKey(child)) {
reference.setText(table.get(child).toString());
} else {
reference.setText(Integer.toString(table.size()));
serializeHelper(child, target, table);
}
return reference;
} else {
Element value = new Element("value");
value.setText(child.toString());
return value;
}
}
}
===============================
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.LinkedList;
import java.util.List;
public class Mopex {
public static Method getSupportedMethod(Class cls, String name,
Class[] paramTypes) throws NoSuchMethodException {
if (cls == null) {
throw new NoSuchMethodException();
}
try {
return cls.getDeclaredMethod(name, paramTypes);
} catch (NoSuchMethodException ex) {
return getSupportedMethod(cls.getSuperclass(), name, paramTypes);
}
}
public static Field[] getInstanceVariables(Class cls) {
List accum = new LinkedList();
while (cls != null) {
Field[] fields = cls.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
if (!Modifier.isStatic(fields[i].getModifiers())) {
if (!Modifier.isPublic(fields[i].getModifiers()))
fields[i].setAccessible(true);
accum.add(fields[i]);
}
}
cls = cls.getSuperclass();
}
Field[] retvalue = new Field[accum.size()];
return (Field[]) accum.toArray(retvalue);
}
}
===============================
public class Animal {
private String name;
private String gender;
private String classification;
private int weight;
public Animal(String name,String gender, String classification, int weight) {
super();
this.classification = classification;
this.gender = gender;
this.name = name;
this.weight = weight;
}
}
==============================
import java.util.ArrayList;
import java.util.List;
public class Zoo {
private String city;
private String name;
public Zoo(String name, String city) {
this.city = city;
this.name = name;
}
List animals = new ArrayList();
public void add(Animal panda1) {
animals.add(animals);
}
}
=========================
import org.jdom.Document;
import org.jdom.output.XMLOutputter;
public class ZooTest {
public static void main(String[] args) {
Animal panda1 = new Animal("Tian Tian", "male",
"Ailuropoda melanoleuca", 271);
Animal panda2 = new Animal("Mei Xiang", "female",
"Ailuropoda melanoleuca", 221);
Zoo national = new Zoo("National Zoological Park", "Washington, D.C.");
national.add(panda1);
national.add(panda2);
try {
XMLOutputter out = new XMLOutputter();
Document d = Driver.serializeObject(national);
out.output(d, System.out);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
posted @
2005-08-17 09:35 Dave 阅读(160) |
评论 (0) |
编辑 收藏
想在企業階梯中順利地一階一階往上爬?「今日管理」(Management Today)
雜誌日前指出,工作者應該注意幾個獲得升遷的秘訣:
1.願意多做一些。願意主動多做一些工作,可以贏得同事的感激,也顯示
了你已經準備好承擔更多的工作職責。
2.積極建立人際網路。無論公司內外,你認識的人越多,獲得新職務的機
會就越大。
3.執行深入細節,但是看法擴及整體。讓別人覺得你會思考公司的重要議
題,謹慎選擇適合的議題,表達你對該議題的看法。
4.熱情具有傳染性。展現出你對公司的熱情及忠誠,如果你的活力可以影
響其他人,公司會希望讓你扮演更重要的角色。
5.協助會議更順利進行。在會議中發揮助攻效果,顯示出你的獨特之處,
並且與別人建立更好的關係。
6.避免一般的事業生涯發展途徑。明天的領導人需要的經驗,可能與今天
的領導人不同,特別的事業生涯發展經歷,可以讓你在同事中鶴立雞群。
7.幾年更改一次職責。讓你保持對工作的新鮮感,也給予你更廣博的經驗
,增加競爭力。
8.有焦點,但也具彈性。決定自己想要的職務,想要的工作技能,以及你
將如何獲得它們,目標明確,但是也願意接受出現的新機會。
posted @
2005-08-16 09:30 Dave 阅读(97) |
评论 (0) |
编辑 收藏
The class diagrams are essentially the same, but the two patterns differ in their
intent.
With the State Pattern, we have a set of behaviors encapsulated in state objects; at any time the context is delegating to one of those states. Over time, the current state changes across the set of state objects to reflect the internal state of the context, so the context's behavior echanges over time as well. The client usually knows very little, if anything, about the state objects.
With Strategy, the client usually specifies the strategy object that the context is composed with. Now, while the pattern provides the flexibility to change the strategy object at runtime, often there is a strategy object that is most appropriate for a context object.
In general, think of the Strategy Pattern as a flexible alternative to subclassing; if you use inheritance to define the behavior of a class, then you're stuck with that behavior even if you need to change it. With Stategy you can change the behavior by composing with a defferent object.
Think of the State Pattern as an alternative to putting lots of conditionals in your context; by encapsulating the behaviors within state objects, you can simply change the state object in context to change its behavior.
posted @
2005-08-15 14:13 Dave 阅读(105) |
评论 (0) |
编辑 收藏
职员为什么跳槽?是嫌钱少,还是嫌职位低?最大的原因是“我讨厌这个老板!”因为不满老板而跳槽,因为喜欢经理就投奔,看来,“攻心为上”这句名言千古不变。如果你能留住并且不断吸引人才,就说明你是一位出色的管理者。
一定程度的人员流动是不可避免的,它向企业进步和招聘新的优秀人才敞开了大门,使企业能够充满活力。然而,过多的人员流失将不可避免地导致企业松散和成本增加。突然而来的意外人员变更将会对客户服务和公司运营造成重创。
所有这些问题的关键在哪里?答案却是出人意料的简单。公平合理的补偿和个人发展的机会常常是非常重要的因素,然而大多数员工离开公司却是因为另外一个原因:令人生厌的老板。
员工不是离开公司,他们是离开老板
国外最近对20000名刚刚离开老板的员工进行了一项调查,调查发现,落后的监督管理方式是员工辞职的主要原因。员工留在公司时间的长短,很大程度上取决于他和经理的关系好坏,如果他们的关系不好,就很难得到晋升的机会。
来自盖洛普的测验显示,75%雇员的离职是离开他们的主管而非公司。在一家跨国公司200名离职人员中,只有40人在离职时进行了薪酬谈判,其中27人因公司加薪留了下来,这27人中又有25人在1年后仍然选择了离开,他们中大多数人离开的理由就是“令人讨厌的上司”。
美国的一项研究报告也显示,员工当初如果以薪酬为理由向公司提出辞职,在他们离开公司3至6个月后跟踪离职面谈中,这一原因往往会让位于其他主导原因,出现频率最高的便是“对主管不满”。很多人当初加盟某个单位的主要原因,是冲着该公司在社会上的知名度和在该行业里的主导地位。当分配到某个部门后,日常工作中更多的将是直接面对该部门经理,作为员工的顶头上司,如果该部门经理不是非常优秀,或者该部门工作对公司全局没有重要性,部门业务未见大的起色,那么部门内的员工就会士气低落,时间一长,优秀人才必然会萌生去意,另寻其他更好的发展机会。
除了主管要求员工超量、超时工作、独揽大权外,引起员工对主管不满的还有主管任命随心所欲,伤了员工的心;主管制造内耗,恶化团队工作;主管不以身作则,常常以身试法;主管任人唯亲,排斥异己等原因。
至于“主管问题”为何会被离职人员隐藏起来,一是员工自己心里不愿承认或者接受是因与主管关系不和而导致自己辞职的事实;二是提出辞职后,像放行日期、有关薪酬的结算以及今后其他企业前来进行背景调查都可能和主管有关系,自己的命运还掌握在主管手中;此外就是怕暴露出自己人际关系处理能力的薄弱,影响将来的求职等。这些都导致员工会寻找另外的原因来作为离职的理由。许多雇员流动或薪资调研报告中,人际关系在雇员流动原因中排在第五位后,导致“主管问题”没有受到管理层的足够重视。
与其费力留人才,不如先培养优秀经理
公司如何才能留住员工?从更广的范围来说,如何才能提高生产效率和激发工人的工作热情?
通过培养个人和公司的关系,使员工对公司有一种家的感觉,其中包括个人的责任具体化、远期学习的机会和大量的非正式的、不拘束的信息反馈和交流。完成这项工作几乎总是从同员工直接接触的第一线的经理开始。现在是让经理们负起责任的时候了。
不少人力资源专家都一致赞同这样一个观点:雇员真正想要的,常常是那些经理简单就能给与的东西。
防止员工流失工作的公司,应该把重点放在使工作吸引人和对经理的培训上,要把他们培养成有魄力、灵活和富于观察的经理。让我们看看国际知名公司的成功经验。
开放式沟通交流——Container Store公司是以达拉斯为基地的一家著名零售商。它被财富杂志评为全美国最优秀的工作场所。这里的人员流动率只有20%,而大多数的零售业中的人员流动率通常在80%-120%之间。
第一年,该公司全职员工要接受大约235小时的培训,并且向他们提供正式和非正式的与经理互动交流的机会。经理不但要让员工知道做好工作的注意事项,并且还要定期接受培训,如何为员工提供必要的援助。以经理主管领导层所称的“直接沟通”经营管理哲学为指导原则,公司的两千多名员工定期讨论公司销售额、公司目标和远景计划等,在确保开放和沟通的环境中阔步向前。
胡萝卜比大棒有用——金融服务业的巨头美国万国宝通银行也开始对经理进行培训,使他们知道如何成为被公司视为作用“日渐重要”的员工们的良师益友。这些经理常常十分乐于使用内部晋升的激励制度,激发员工的自信心和成就感,特别是在员工想另谋高就时能够留住人心。
成为员工的良师益友——Autodesk Inc.是位于加利福尼亚San Rafael的一家著名电脑软件公司。其人力资源专家和培训专家最近设计了一项关于员工保持力的网上培训计划,经理们经过培训之后将会掌握一定的技巧,运用这些技巧可以了解员工的个人事业目标,成为技能娴熟的职业顾问。在特定时期内,他们可以根据实际情况制定一个同时适用于公司和员工的具体发展计划,这样的双赢局面自然会吸引很多想在职业上有所发展的员工。
留不住人,就让经理对员工流失负责
如何确实让经理们对下属员工的流动负起责任?
这里还有一个简单而有效的方法,可以鼓励和帮助经理们降低人员的流动性:把他们的福利补偿和员工的流动率联系起来。如果保持了较低的流动率,那么就对他们进行奖励。反之,如果摩擦不断,员工离职率很高则对他们进行处罚。这是一个很行之有效的战术手段,但是还有待于大家的广泛关注。
大多数经理都很讨厌把他们的收入和其他的因素联系起来。但是,越来越多的公司正在认识到员工的去留关键在于他们的经理。这种事实正在被大家广泛的实践,因为大多数的保留员工的计划在实施的时候都简单易行且成本很低。当然,使经理们接受赞同员工保留计划和方法并不那么一帆风顺。一些人说他们所做的努力对改变现在人员流动的现状的影响力太小。另外一些人则认为这将耗费他们太多的时间。但是,如果人力资源工作人员能够给他们开始这项工作的机会、把他们引导到正确的方向上来,并且向他们展示和说明留住优秀人才他们完全能够做得到,完全能够控制得了,那么经理们就会开始工作。
通过联合最优秀的人才,并给他们分派有意义的工作、给他们提供发展机会和晋升的机会,经理能够成为更出色的老板。这是一个在竞争中生存的问题。
posted @
2005-08-15 13:21 Dave 阅读(81) |
评论 (0) |
编辑 收藏
A hook is a method that is declared in the abstract class, but only give an empty or default implementation. This gives subclasses the ability to "hook into" the algorithm at various points, if they wish; a subclass is also free to ignore the hook.
posted @
2005-08-15 09:55 Dave 阅读(139) |
评论 (0) |
编辑 收藏
生命是一种过程。
事情的结果尽管重要,但是做事情的过程更加重要,因为结果好了我们会更加快乐,但过程使我们的生命充实。人的生命最后的结果一定是死亡,我们不能因此说我们的生命没有意义。世界上很少有永恒。恋爱中的人们每天都在信誓旦旦地说我会爱你一辈子,这实际上是不真实的。最真实的说法是:“我今天,此时此刻正在真心地爱着你。” 明天也许你会失恋,失恋后我们会体验到失恋的痛苦。这种体验也是丰富你生命的一个过程。
两点之间最短的距离并不一定是直线。
在人与人的关系以及做事情的过程中,我们很难直截了当就把事情做好。我们有时需要等待,有时需要合作,有时需要技巧。我们做事情会碰到很多困难和障碍,有时候我们并不一定要硬挺、硬冲,我们可以选择有困难绕过去,有障碍绕过去,也许这样做事情更加顺利。大家想一想,我们和别人说话还得想想哪句话更好听呢?尤其现在这个比较复杂的社会中,大家要学会想办法谅解别人,要让人觉得你这个人很成熟,很不错,你才能把事情做成。
只有知道如何停止的人才知道如何加速。
我有位朋友在学滑雪的时候,最大的体会就是停不下来。他刚开始学滑雪时没有请教练,看着别人滑雪,觉得很容易,不就是从山顶滑到山下吗?于是他穿上滑雪板,赤溜一下就滑下去了,结果他从山顶滑到山下,实际上是滚到山下,摔了很多个跟斗。他根本就不知道怎么停止、怎么保持平衡。经过反覆练习,终于学会了在任何坡上停止、滑行、再停止。这个时候他就发现自己会滑雪了,就敢从山顶高速地往山坡下冲。因为他知道只要想停,一转身就能停下来。只要你能停下来,你就不会撞上树、撞上石头、撞上人,你就不会被撞死。因此,只有知道如何停止的人,才知道如何高速前进。
放弃是一种智慧,缺陷是一种恩惠。
当你拥有六个苹果的时候,千万不要把它们都吃掉,因为你把六个苹果全都吃掉,你也只吃到了六个苹果,只吃到了一种味道,那就是苹果的味道。如果你把六个苹果中的五个拿出来给别人吃,尽管表面上你丢了五个苹果,但实际上你却得到了其他五个人的友情和好感。以后你还能得到更多,当别人有了别的水果的时候,也一定会和你分享,你会从这个人手里得到一个橘子,那个人手里得到一个梨,最后你可能就得到了六种不同的水果,六种不同的味道,六种不同的颜色,六个人的友谊。人一定要学会用你拥有的东西去换取对你来说更加重要和丰富的东西。所以说,放弃是一种智慧。做人最大的乐趣在于通过奋斗去获得我们想要的东西,有缺点意味着我们可以进一步完美,有匮乏之处意味着我们可以进一步努力。
决定行动,行动产生结果。谁都能做梦想家,只有行动才能体现时间的价值。我要珍惜生命中的时光,我将立即开始行动!
posted @
2005-08-12 13:27 Dave 阅读(76) |
评论 (0) |
编辑 收藏
杨修终于被曹操杀了,杨修觉得死得冤,死得太不值了,所以他的魂魄不愿投胎。等啊等,有一天,他见到了曹操的亡魂,急忙上前问道:"明公慢走,你当初为什么要杀我?"曹操一看是杨修,便停住了脚步,笑了一下,答道:"你想知道我为什么要杀你吗?听我慢慢道来。你的智力过人,非常聪明,你上知天文,下查地理,懂奇门,会八卦,可以说是一个奇才。但是你恰恰忘记学习一门人生的必修课,那就是领导者的心态。所以你不晓人和。今天闲着也是闲着,我给你补上这一课。
领导,作为一个成功人士来讲,曾经遭受过多少坎坷,又遭受过多少艰辛,还遭受过多少他人的冷眼,你知道吗?在创业阶段流过多少汗,淌过多少泪,吃过多少苦,你知道吗?成功后又承受着多大的压力,面对着多大的困难,忍受着多大的指责,你知道吗?他们不缺钱花,也不缺衣穿,唯独缺少的就是他人的认可,希望的是别人来赞美他几句,哪怕是唯心的,起码让他觉得他的努力没有白费。而现实呢,没有人这么做,他们招来的只有嫉妒的目光和无穷的排挤。这些你知道吗?孤独是领导者的难言之隐,他们不敢奢求其他人来赞美他,让自己的下属赞美一下,这个要求过分吗?不过分!一点儿都不过分!但是你,杨修,没有做到,相反处处和我作对。记得有一次我拿给你们一盒点心,只不过想让你们来和我说一声想吃,我不会不给你们吃的,兴许我还会多给你们几盒。我在盒上写了'一合酥',意思就是让你们不知道其中的含义,而来向我请教,然后我会告诉你们,'合'字下面没有'皿',也就是说,没有东西盛放,你们无法吃,我把盘子给你们,你们不就能吃了吗,这样显得我既聪明,又和蔼,有什么不好,可是你偏要把它理解为'一人一口酥',全给我吃掉了,你说,当时我的面子往哪儿搁啊,我的心里能平衡吗?不能!
记得有一次,好像是工人修一座门,问我是宽一些还是窄一些好,我身材较胖,当然想让门宽一些,但是我要是如果这么直说,显得我太没有水平了,于是我灵机一动,在门上写了一个'活'字,同'门'字合在一起就是个'阔'字。有话不明说,这是领导显示其尊严的一种手段,当人们无法猜出的时候,我再给予解答,你知道吗,这样的感觉是多么多么的爽吗?然而,就是因为你,杨修,我没有爽成,反到让你爽了一下,你毫不留情的把谜底给我揭穿了,你知道后来他们说我什么吗,他们说:'我们的丞相怎么这么爱卖弄啊,简单的事非要搞复杂了。'你让我的尊严荡然无存,我能不恨你吗?
我要在我的两个儿子中选出一个来继承我的大业,曹丕和曹植都是可造之材,我有心考核一下他们的能力,这是关系到我的千秋大业的事情,结果你,杨修,偏要给曹植出谋划策,严重影响了我对他们绩效考核的真实性,从而误导了我的选择方向,你罪不容诛!曹植的落选,和你有直接的关系,你难辞其咎!你的魔爪已伸向了我的家庭,破坏了我们的父子关系,你无情的撕下了我隐私的面纱,你太可恨了!
大家公认我爱才,求贤若渴也是我所追求的目标。当年,弥横是多么的嚣张,当众脱光衣服,敲着鼓骂我,我没有生气;徐庶之母当众数落我的不是,还用砚台打我,我还是没有生气;我待关羽如同至亲,上马金,下马银,三日一大宴,五日一小宴,还把赤兔马给他,但他还是弃我而去,我仍然没有生气。他们这些行为,我都可以忍,唯有你,杨修,让我忍无可忍,你比他们更可恨一千倍,一万倍,因为你是我的下属,是我一手把你栽培到今天,所以你最可恨。那个时候,我就已经暗下决心,要把你杀死,只是缺个机会而已。
我带兵去汉中攻打刘备,久战不胜,反而损兵折将,当时确有退意,可是我并没有表态,而你却自作聪明,把我的口令'鸡肋'引申为'食之无味,弃之可惜',说我要退兵,搞的军中将士心无战意,我被你逼的没有选择了。我真不明白我这个领导者在你面前,居然被你左右,你是我的领导,不,你是我的祖宗!不过这次你还不知道,你聪明到头了,正好给了我杀你的机会,我不能错过这个机会了,如果我错过这次机会,今后在你面前,我永远都是孙子。
我还是那句话,你的确很聪明,但正是你的小聪明,把你的性命害了,应了古训,'聪明反被聪明误'.你太爱耍小聪明,已达到了忘我的境界了。你眼里跟本就没有'领导'这个概念。所有的人当中,就你敢拿领导'开涮',就你敢挑领导的毛病,就你敢违抗领导的命令。有句俗话,你应该知道,'老虎的屁股摸不得',你偏要摸,可想而知,你是在自寻死路!"杨修听到这里,"扑通"一声跪倒在地,"曹丞相,我服了,我杨修是生的窝囊,死的活该。我这辈子算是白活了,不过今天这节课补得好啊,我全明白了。时候也不早了,咱们一同去投胎吧,来世我还做您的下属。"曹操哈哈大笑,挽着杨修的胳膊走向了奈何桥。但由于他们谈话的时间太长了,比别人晚投了一千多年。
从此,人世间多了一对君臣:乾隆与和珅。
posted @
2005-08-12 13:19 Dave 阅读(105) |
评论 (0) |
编辑 收藏
1. Both FM an AFM create objects. But FM do it through inheritance and AFM through object composition.
To create objects using FM, you need to extends a class and override a factory method. the whole point of the FM Pattern is that your're using a subclass to do your own creation for you. In that way, clients only need to know the abstract type they are using, the subclass worries about the concrete type. So, in other words, FM keep clients decoupled from the concrete types.
AFM provides an abstrct type for creating a family of products. Subclasses of this type define how those products are produced. To use the factory, your instantiate one and pass it into some code that is written against the abstract type. So, like FM, the clients are decoupled from the actual concrete products they use.
2. AFM group together a set of related products
3. AFM often use factory methods to implement it's concrete factories.
4. use AFM whenever you have families of products you need to create and you want to make sure your clients create products that belong together. use FM to decouple your client code from the concrete classes you need to instantiate, or if you don't know ahead of time all the concrete classes you are going to need , just subclass and implement the factory method.
posted @
2005-08-12 11:03 Dave 阅读(156) |
评论 (0) |
编辑 收藏
1. No varible should hold a reference to a concrete class.
If you use new, you'll be holding a reference to a concrete class. Use a factory to get around that.
2. No class should derive from a concrete class.
If you derive from a concrete class, you're depending on a concrete class. Derive from an abstraction, like an interface or an abstraction class.
3. No method should override an implemented method of any of its base classes.
If you override an implented method, then your base class wasn't really an abstraction to start with. Those methods implemented in the base class are meant to be shared by all your subclasses.
posted @
2005-08-12 09:42 Dave 阅读(87) |
评论 (0) |
编辑 收藏
think of Simple Factory as a one shot deal, while with Factory Method your are creating a framework that let's the subclasses decide which implementation will be used. Simple Factory gives you a way to encapsulate object creation, but doesn't give you the flexibility of the Factory Method because there is no way to vary the products your're creating.
posted @
2005-08-11 17:16 Dave 阅读(85) |
评论 (0) |
编辑 收藏
A factory method handles object creation and encapsulates it in a subclass. This decouples the client code in the superclass from the object creation code in the subclass.
1. A factory method is abstract so the subclasses are counted on to handle object creation.
2. A factory method returns a Product that is typically used within methods defined in the superclass.
3. A factory method isolates the client from knowing what kind of concrete Product is actually created.
4. A factory method may be parameterized(or not) to select among several variations of a product.
posted @
2005-08-11 16:02 Dave 阅读(122) |
评论 (0) |
编辑 收藏
日本索尼公司的盛田昭夫曾经说过:“日本公司的成功之道并无任何秘诀和不可言传的公式。不是理论,不是计划,也不是政府政策,而是人,只有人才会使企业获得成功,因此,衡量一个主管的才能应该看他是否能得力地组织大量人员,看他或者她如何最有效地发挥每一个人的能力,并且使他们齐心协力,协调一致。作为主管,待人应该真心诚意,如果你要发挥人的作用,钱并不是最有效的工具,你应该把他们融为一家,对待他们象对待你的家人一样。”在这里,盛田所谈到的就是强调主管在日常管理事务中应该运用的领导方法和领导艺术,以更好的团结下属,发挥团队精神和作用。可以这样说,在公司发展的任何阶段,作为主管,都需要身先士卒,带领下属共同奋斗,而在这其中,主管的领导方法和领导艺术将起到很大的促进作用。
与员工保持亲密的距离
现代办公室好比一个大家庭,蕴含着其所有的和谐与不睦之处。因此,主管与员工的关系问题至关重要。作为主管,你要使员工感到既安全又独立,既得到信任又不感压抑,既可以提出个人问题也不怕生活受到干扰。
心理学家Robert Rosen(罗森)是美国华盛顿特区一家管理顾问公司的主要负责人。他说:“企业需要员工对自己的行为担负更多的责任,以便成为企业的活跃伙伴。同时,企业必须在效率管理上担负更多职责,这也许意味着他们不得不更加留意与员工的关系。”那么,与员工保持良好的关系恐怕不是嘴上说说就可以的,需要主管们能够与员工保持比较亲密的联系,以使他们感到你平易近人,有什么事情可以找你帮忙。如果主管确实能够在日常工作中注重这些,员工们会更加投入地工作。如今你投之以桃,将来他们很可能在工作上报之以李。
而另一些高高在上、远离员工的主管,会使员工感到自己与其说是有血有肉的共事者,还不如说更象机械人,在这种环境中,员工的问题将不断恶化,直到已无法补救才来一次总爆发,最终的结果只会阻碍公司的正常发展。
建设一个优秀的团队
当今的许多主管深切感到,自己就象一个初出道的空中飞人演员。由于他们所领导的企业组织正在向团队方向发展,所以他们必须从一个舒适、安全的平台(即他们企业组织的传统文化)跳到另一个平台(即进行自我管理的团队)。他们必须放弃一统天下的领导方式,学会授权赋能。可惜的是,这种变革并不被看作是一个振奋人心的过程,相反却使许多主管焦虑不安。为什么?因为很多主管不知从何入手,而他们所领导的企业组织也不清楚该怎样去帮助他们。
一个优秀团队的建设刚开始时,主管们不得不花很多时间和精力来带动你的团队。必须明确团队目标、员工的角色和责任。此后不久,主管需要花40%到60%的时间训练员工去做你以前做的工作,如安排假期、分配每天的任务、生产监控等。
在这一成长阶段,可以让团队成员尽可能多地承担一些不会引致太大后果的任务。当团队适应了新的职责后,帮助他们扫除障碍并提供各种所需资源。这一阶段你需要注意以下方面:要坚持不懈,在变革过程中,几乎所有团队主管都经历过至少一次的彻底失望,然后,就会出现一个突破:团队成员或者成功地完成一项新任务,或者学会运用一项新技能,甚至会开始感谢你给予他们的帮助;注意观察团队的进步情况,如提前完成任务或者在某一领域展示了高度的主动性;树立责任感,当团队自始至终地负责一项任务时,腔岱浅H刃牡囟源庀钊挝瘛?/P>
在这一阶段,你的团队需要你的帮助。因此,要为他们投入一些你的个人时间,不断为他们提供反馈,给予适当的指导。
团队经过一段时间运作以后,他们能够很好地处理人际关系问题、很好地合作,并能使业绩保持在一个稳定的水平。这时,你的团队已经不象从前一样离不开你,因此你有更多时间谋求自己的发展。你可以在某一领域深入下去,也可以负责改进一些跨部门的工作流程,还可以想出一些能为公司或客户增殖的好办法。在这一阶段,你的团队可能已发展到顶峰,为避免滋生松懈或自满情绪,需经常提醒他们团队的目标并帮助他们认清新的任务和挑战。继续为他们举办庆祝活动,不断激励团队进步,为团队的壮大和发展提供原动力。
营造一个和谐宽松的环境
在一个公司中,营造一个和谐宽松的工作环境决定着员工的心情。而这种环境的营造,良好的物质环境当然重要,软环境也同样重要,而主管就是软环境的建设者和维护者。在这样的软环境营造过程中,美国著名企业家玛丽?凯的《用人之道》教给我们很多知识:
第一,希望别人怎样对待自己那样去对待别人,管理中的金科玉律就是:“你们愿意别人怎样对待你们,你们也应该那样去对待别人。”
第二,相信每个人都有专长,必须使别人感到他们自己很重要。一个主管怎样才能使人们感到自己重要?首先是倾听他们的意见,让他们知道你尊重他们的想法,让他们发表自己的见解;其次是既要人们承担责任,又要向他们授权,不授权会毁掉人们的自尊心;最后,应该用语言和行动明确地告诉人们你赞赏他们。
第三,把听意见当作头等重要的大事来抓,掌握听意见的艺术,聪敏的管理者是多听少说的人。
第四,批评要讲策略。假如某人的工作不能令人满意,你决不可绕开这个问题,而必须表达自己的看法。不过,在提出批评时,一定要讲究策略,否则就有可能出现适得其反的结果。这里应该注意的是:1、决不当众批评人;2、要记住批评的目的是指出错在哪里,而不是要指出错者是谁;3、要创造出一种易于交换意见的气氛,明确“同自己员工保持亲密的关系是正常的”,因此对员工既要关心,又要严格,既要十分亲热,又不能损害自己的监督作用;4、无论批评什么事情,都必须找点值得表扬的事情留在批评前和批评后说。
第五,给别人以热情。一个能激起热情的平凡主张比一个不能激起热情的非凡高见好得多,因此,主管者必须能激起部下的热情。要实现这一目标,主管本人必须首先要有热情。一帆风顺时保持热情并不难,但是在逆境中要保持热情却不太容易,这时,必须强迫自己保持热情直到自己身上自然而然地产生出热情,正如顾客的购买欲望会因为售货员的冷漠态度而消失,所以主管的工作态度会影响其他人的热情。如果一位主管对部下提出的新方案三心二意,那他十有八九得不到部下的支持,因此,缺乏热情有可能导致毁灭性的后果。
第六,敞开办公室的门。开门有两个目的:一是使来访者对公司有个好印象,二是为公司内部人员提供增进了解与彼此合作的机会。开门的内容,一是员工可以直接找主管交谈,二是公司所有的人都彼此直呼其名,三是主管向同事表示极大的热情,好主管应当是集体的一员。
第七,创造一种使部下热爱本职工作的环境。人们越是热爱自己的工作,干劲就会越大,也会把那项工作干得更好。因此,每个主管都应该努力创造一种使自己的部下能够热爱本职工作的环境。实现这个目标的一个方法是,创造一种使自己的部下感到自由和无拘无束的气氛,因为人们在心情十分压抑的情况下不可能干出最佳水平。另一个方法是,承认各人的志趣有差别,区别对待每一个人,分配他们去干自己有兴趣的工作,精明的主管还会发现某人什么时候缺乏做某种工作所需要的爱好,他会尽力找出更适合此人干的工作。最后还有一个方法,就是主管自己对本职工作像对业余爱好一样,以自己的工作热情去感染部下,而不是用自己的消极情绪去影响部下。
成功运用每一个下属的长处
人力资源管理中有一句名言,没有“平庸的人”,只有“平庸的管理”。每个人总是有长处的,高明的主管善于从每个普通的员工身上,发现有价值的东西,并加以引导和开发。一位香港企业家认为经营管理人员有三个层次,第一个层次是商人,只做生意;第二个层次是企业家,拥有一份实业;第三个层次是组织者,是运筹帷幄的人。而组织者最主要的才能是善于把每个人安排到适当岗位上去。
主管的任务在于运用每个人的长处,把每个人的长处作为共同绩效的建筑材料来建成组织的大厦,这几乎是人之常识。试想一下,哪个单位的绩效不是各个成员发挥各自的长处共同做出来的?因此,主管在用人的时候,要首先把着眼点放在人的长处上,弄清这个人有什么长处,如何用他的长处。唐太宗李世民曾说:“我成功的原因只有五条:……第二,一个人做事,不能样样都会,我用人总是用他的长处,避免用他的短处”。
然而,许多主管却首先盯住了人的短处,这个不能让他做,那个不能让做,甚至思来想去,这个人什么也不能做,成了“废”人。一个主管如果不能发掘人的长处并设法使长处发挥作用,那么他就只能受人的短处的影响,被短处的阴影所笼罩。从人之短处来用人,那是误人前程,甚至可以说是“虐待”人。至于短处,那是人人都有的,主管、管理者当然也要看到人的短处,也要设法帮助克服。设法不让短处对集体和他人发生影响,避免损害组织的绩效。但必须是在发挥长处的前提下来克服短处,不能本末倒置。事实证明,人的长处得到发挥了,他也就乐于接受批评,克服短处。
分析下属特点酌情对待
对不同类型的人美国心理学家赫兹伯格有个双因素理论。他把人的需要分成两种因素,工资、待遇和工作环境等叫保健因素,成长、成就等叫激励因素。他认为不同的人追求不同,因而对这两种因素的需要也不同。就是说,可以根据这两种因素区分人的不同层次。他的这个理论是有一定道理的。按照他的理论,一味在事业层面上追求激励因素的人我们称之为主动型的人;一般追求保健因素的人我们称他们为被动型的人。
—主动型的人。主动型的人一般具有较高的追求和奉献精神,具有较为丰富的思想内涵,他们的主动意识强,往往表现出开拓精神来。对他们之间能力强的,我们应该以授权方式为主,尽量放权给他,可以交给他们复杂的、有难度的,特别是富有挑战性、风险性和开拓性的工作。这不只是可以培养他们能力,而且会激发他们更大的创造精神。一些人甚至认为,具有高追求的人,交给他们只具有50%成功率的工作,会调动起他们最大的干劲和热情。对他们之中能力弱的人,我们应该尽可能为他们提供学习、提高水平的条件,为他们创造好的环境,帮助他们进步,尽量交给他们有把握完成的工作,逐渐提高能力。
—被动型的人。这部分人比较注重物质利益、工作条件和人际环境,他们表现出来的往往是责任心,而不是进取心,思想内涵也比较简单。对他们其中能力强的,要明确其具体责任,赋予确定的激励机制。因成就意识较弱,所以最好是叫他做某一领域、某一方面的工作,或是技术性较强的工作。对其中能力较弱的人,一定要辅以较为完美的管理制度和激励办法。分配给他们较为单一、专一的工作则比较合适。
对个性突出、缺点、弱点明显的能人这就是我们常说的两头冒尖的人。对他们,一是用长。长处显示出来了,弱点便被克制,也容易得到克服。二是做好思想和情感沟通的工作。一年中谈几次话,肯定成绩,指出问题,沟通感情。使他们感到主管的关心和理解,自己也会兢兢业业。三是放开一点,采取一忍二等的办法。不要老是盯住人家,而是给人家留有一定的余地,帮助也只是在大事上、在关键性的问题上。否则,束缚住手脚就很难有所作为。
对有特殊才能的人一定要尽可能给他们最好的条件和待遇。他们之中有的人并不是安分者,可能有这样那样的问题,以致很不好管理。对此我们不只是要容忍,而且应该做好周围人们的工作,以便使他们能够集中精力发挥长处和优势。在特殊的情况下,还应该放宽对他们的纪律约束和制度管理,甚至采取明面掩盖、暗中支持的办法。
对有很强能力的人采取多调几个岗位、单位的办法,即能够让他们发挥多方面的、更大的作用,又可以调动他们乐于贡献、多出成绩的积极性。对年轻又很有能力的人,则应该给几个轻便的台阶,让他们尽快地负起更大的责任。如果有可能,我们可以为他们创造条件,让他们去开拓新的事业。
对被压住了的能人一个是先把他们调出去,给他们显示自己本领的机会,也给他们从另外的角度审视自己的空间。等有了成绩,被公众认可,在必要时就可以调回来加以任用。另一个办法是把压他们的人调开,让能人上来。这都根据具体情况决定。
结束语
兵有兵经,但兵无常势,弈有弈谱,但弈无定型。所以,主管们在经营过程中要懂管理学、经营学,但如何管、如何经营却要依靠精湛的艺术去描绘。
posted @
2005-08-11 13:29 Dave 阅读(78) |
评论 (0) |
编辑 收藏
- crust :外壳,面包皮;盖以硬皮,结硬皮
- crispy : 易碎的; 精神爽快的
- dough : (名) 生面团; 钱, 现款; 似生面团的东西; 布丁
- sauce : 调味, 使增加趣味 酱油, 果酱, 调味料
- toss : 抛, 投, 扔; 把...抛来抛去; 使上下摇动; 突然抬起; 摇摆, 辗转, 颠簸 投掷, 摇摆, 抛
- diagonal : 对角线, 斜列, 斜线 (形) 对角线的, 斜纹的, 斜的
- strive for : 努力, 奋斗, 苦干; 反抗, 斗争
- lurk : 潜藏, 埋伏, 潜伏; 偷偷摸摸, 鬼鬼祟祟, 潜逃; (因特网用语) 作为讨论组里的被动成员 (只读其他人的谈话而不加入阐述自己的意见) 潜伏; 埋伏
- dissect : 解剖; 仔细分析; 切开; 细心研究
- volatile : (形) 挥发性的, 不稳定的, 可变的
- feat : 壮举, 技艺表演, 功绩
- intercede : 仲裁; 求情; 说项
- regression : 复原, 退步, 逆行
- hypothetical : (形) 假设的, 假定的
posted @
2005-08-11 13:28 Dave 阅读(69) |
评论 (0) |
编辑 收藏
一流的沟通者却像一位合气道高手,能敏锐地测知阻力的所在,找出双方相同的观点,然后借势顺使,把整个沟通导向自己所要的方向。
在我们的话里面,有些字眼会引起别人的抗拒和争论,我们要特别留意以避免之,这也是一流的领导者或沟通者成功之处。富兰克林曾在他的自传里谈到他不伤和气的沟通技巧:
“当我在推动任何可能引起争论的事情时,我总是以最温和的方式表达自己的观点,从来不使用绝对确定或不容怀疑的字眼,而代之以下列说法:据我了解,事情是这样子;如果我没犯错,我想事情该是这样;我猜想事情是不是该这样;就我看来,事情是不是该如此?像这样对自己看法没多大把握的表达习惯,多年来使我推动许多棘手的问题一帆风顺。”
富兰克林实在是深谙说话的重要,避免使用肯定的字眼来说服别人接受他的观点,以免造成抗拒。在我们的生活里,有一个字颇具杀伤力,可是我们用得太习惯而浑然不觉,那个字就是“但是”。
如果有人说:“你说的有道理,但是……”你知道他是什么意思吗?他是指你说的没道理或不相关。“但是”这个字具有否定先前所说的意义。如果有人在同意你的观点之后,再加上“但是”这两个字,你会有什么样的感觉呢?我相信你心里不见得会痛快的。
如果你把“但是”这个字替换成“也”的话,会有什么结果呢?如果你这么说:“你说的有道理,我这里也有一个满有道理的看法……”或“那是个好主意,我这里也有一个满好的主意……”你猜会有什么结果呢?这两句话都是以同意对方观点开头,然后给自己的观点另开一条路,未曾造成对方抗拒的心理。
我们要牢牢记住,在这个世界里没有永远抗拒的人,只有顽固且不具弹性的沟通者。就像有些话会必然地激起听者的抗拒,然而也有些话能使听者敞开心门,愿意与你沟通。
例如,如果你懂得沟通的技巧,在坚守原则的立场下,既充份表达了自己的观点,也未激起他人的反对,请问你会有什么感觉?你是否会认为那个沟通技巧十分高明?
现在就让我告诉你这套技巧,我称其为“合一架构”。这套架构只有三句话,我希望你在与人沟通时能常常运用,使你与人和睦,充份表达己见。请记得,惟有在没有抗拒的地方,才不会有冲突。 这里就是合一架构的那三句话:
“我感谢你的意见,同时也……”
“我尊重你的观点,同时也……”
“我同意你的看法,同时也……”
在上面的每一句话里,你都表达了三样事。第一,你能站在别人的立场看这件事,而不以“但是”或“不过”的字眼来否定或贬抑他的观点,因而达成契合;第二,你正建立一个使你们携手合作的架构;第三,你为自己的看法另开一条不会遭遇抗拒的途径。
让我举个例子,如果有人对你说:“你百分之百的错了。”而你反顶了一句:“我没错!”你认为双方能平心静气的谈下去吗?我想那是不可能的,这时反倒会有冲突、有抗拒。相反地,如果你这么说:“对于这件事,我十分尊重你的看法,同时也希望你能站在我的立场听听我的看法。”
注意,在沟通时你无需赞同他的主张,但是你一定得尊重他的立场,因为毕竟各人有各人的认知方式和情绪反应。
你也可以尊重别人的意图,例如,经常有人因为对某件事意见相左,继而不尊重别人的意见,甚至听而不闻。如果你能善用合一架构的观念,你就会注意他的意图而不在意他所说的,在这种理性反应下便能寻出一些新的沟通方式。
假设你与某人在核武问题上相互争论,他主张建立核子打击武力,而你主张冻结核子武力。虽然你们的看法是南辕北辙,但是出发的动机却是相同,都希望确保自己和家人的安全,以及世界的和平。
因此对方如果这么说:“要想解决两强的核武问题,惟一的办法就是让苏联知道美国的核子武器足以毁灭对方。”这时你可别跟他争论,相反地你应站在他的立场说道:“我十分感谢你如此关心下一代的安全,同时我也相信除了用核武吓阻苏联之外必然还有其他的方法。”
当你采用这个方法沟通时,对方必然觉得受到尊重,也就不会产生争执。这套方法你可用之于任何人,不论对方怎么说,你总能找出他值得尊重、感谢、同意的观点。你不会跟他有任何的争执,因为你根本就不打算争执。
在研讨会里,我有个简单实验,就是让二人一组针对同一题目相互辩论。在辩论当中,我要他们相互质问时不可在话中出现“但是”这个字眼,并且不可贬抑对方的看法。
这个规定有如把合气道用在说话上,对学员们是个蛮新鲜的经验。他们在这个实验中学会尊重别人的看法,不以压服对方为乐;他们能争论但不会交恶;他们能从差异中找出共同的观点。
你也可以找个人照样练习。一番。先订个题目,然后双方依照前面所说的方法相互抒发己见并质问对方,像玩游戏似地去找出共同的观点,引导对方认同自己的观点。
这种沟通方式不需要你放弃自己的原则,也不需要你失去立场,但是你却能慢慢地和对方产生契合,然后引导对方顺从你的看法,更快地达成目的。
我们之中有许多人把讨论看成是一场要决定出胜负的游戏。我们是对的,对方是错的;我们的看法是绝对无误的,对方却是一派胡言。然而从合一架构的观点上,我却能比以前更快地达到自己的目的。
一流的事务员和一流的沟通者都知道,要说服一个人去做他不愿意做的事是很难的,但是要他去做他愿意做的事却很容易。你只要能找出双方认同的观点,然后自然地去引导他,你就能叫他做他愿意的事。因此一个有效的沟通就得尽量避免冲突的发生,减少抗拒的可能。
我们的思想经常囿于旧有的思考模式,难以突破。这就有如电唱机的唱针卡在唱片上的某一条沟纹里,反覆唱着那一句歌词。要想消除这个跳针现象,你不是在唱针头上轻压,使唱针越过卡住的那个部位,就是把唱针提起,再轻放到唱片的另一个部位。我们若不想让自己也卡在旧有的思考模式上,就得换个新的方法。
我发现人们之所以会落入旧有模式中,乃是不知该怎么办。有些人很可能垂头丧气地四处找人倾吐,期望能唤起别人的同情和关怀。这种尽全力引起别人注意的方式,就是他们改变心情的最好方法。
如果你有个这样的朋友,你会怎么办?很可能你就会如他们所期望的,坐下和他们好好地长谈并安慰一番。你这样做可能使他会觉得舒坦一些,不过也因此加强了他这一套模式,因为你的做法无异于告诉他,如果他找人倾吐,他会得到别人的关怀的。
请问你有没有别的办法呢?如果你不理睬他,甚至于当面奚落他,会怎么样呢?这时你将发现他会楞住,无言以对,然后从这阵困惑中清醒,从此就会有新的认知方式了。
有时我们是需要一个好朋友,向他发抒内心的悲伤和痛苦,不过不能养成习惯,否则对你有害。你若能改变这种处事方式,你便能充份地控制自我。
然而有许多人告诉我们,我们无法控制自我的行为、心境和情绪,因此我们只有求助于心理医生,可是又听他们说这是孩提时的精神创伤或荷尔蒙分泌失常所致。难道真如他们所说的那么复杂而改不掉吗?在这里就让我用中止模式的方法,在瞬间改变来证明它的效果。
有一次班德勒说了一个亲身经历的故事,那是他到一间精神病院拜访一位自认为是耶稣的病人。当班德勒一跟他碰面,就问他:“听说你就是耶稣?”他说:“是的,我儿。”班德勒接口道:“我等下再来。”就把那个病人单独扔在那里,好不困惑。
三四分钟后,班德勒带了一把卷尺,从头到脚为那病人量了一下尺寸,就又离去。这番举动又令那个病人困惑了一阵子。过一会儿班德勒回来,带了一把锤子,几根钉子和几块木板,并且开始钉成十字架的形状。
那个自称是耶稣的人问道:“你在做什么?”班德勒在钉下最后一根钉子后再问那位病人:“你是耶稣吗?”那人再次回答:“是的,我儿。”班德勒就说:“那么你应该知道我来此的原因了。”
突然间,那人回复神智,连忙说:“我不是耶稣!我不是耶稣!”他先前的模式被班德勒一下子就终止了。
另外一个终止模式的例子,是数年前所举办的禁烟活动。那场活动建议当自己的亲人想取香烟时,就送给他一个吻以取代那支香烟。这个举动一方面打破他自动取烟的模式,另一方面可让他怀疑旧有的取烟行为是否明智。
像这种终止模式的方式也可用在政界和商界,更可以用在日常生活里。经常我们会和自己周遭的人起争执,吵到最后大家都忘了争吵的原因,只想在这场争执中如何“赢得胜利”,因为这是他们争执的目的。像这样的争执往往会破坏双方的友谊。
有时候在吵完后,你回想起来,总会觉得奇怪,为何会变成这种结果?可是在争执的当时,你可不会想到这一层。你现在想想是否最近有过一次这样的争执,当时你可曾用哪一种终止争执的方式?另外也请你为这种情况想五种终止模式的方法吧!
终止模式也可以做为预警信号,以便在争执失去控制时能切断这种争执。我发现幽默的用语是终止争执最佳的工具。首先你和对方得有一个约定,就是任何一方发现争执有可能会失控时,立刻就把共同认定的那句幽默话说出来,而另一方一听见这句话就得住口。另外由于这句幽默话能引起我们想起某件好笑的事,便能冲消一些争执所产生的火药味。
在本章里所阐述的两个观念,是与我们平日所知道的背道而驰的。第一,同意对方的说辞远比制服对方的说辞更具说服力。我们今天所处的社会充满了竞争,事事都要分出胜负。不过在沟通这件事上,如果想靠言语取胜,往往不会有任何成效。
相反地,你若能以同意取代反对,以引导取代制伏,你的沟通会更有成果。虽然这样做并不容易,但是只要不断地注意,有一天你的沟通方式会改变的。
第二个观念是,我们的行为模式并非牢固地永难更改。如果我们做事的态度一直是消极的、束缚的,那并不是我们的心智出了毛病,只不过是反复使用某种不好的行为模式。
不管那种模式是对别人或对自己,你都得立即终止,改换成另一种新的模式。毕竟我们不是机器人,受设定的程式所摆布。对于自己的心智,我们绝对有自我控制的能力,只要有决心,认清症结所在,改变只是瞬间之事。
上述两种观念都是从弹性的立场衍生出来。当你拼图拼不出来,你不需重复使用一种拼法,你应该以弹性的态度换个方式试试。你的弹性越大,可选择的机会就越多,可发展的空间就越广,而成功便接踵而至,指日可待。
posted @
2005-08-11 09:36 Dave 阅读(101) |
评论 (0) |
编辑 收藏
1. Observable is a class
First, because Observable is a class, you have to subclass it. That means you can't add on the Observable to an existing class that already extends another superclass. This limits its reuse potential.
Second, because there isn't an Observable interface, you can't even create your own implementation that plays well with Java's built-in Observer API. Nor do you have the option of swapping out the java.util implementation for another.
2. Observable protects crucial methods If you look at the Observable API, the setChanged() method is protected. So what? Well, this means you can't call setChanged() unless you've subclassed Observable. This means you can't even create an instance of the Observable class and compose it with your own objects, you have to subclass. The design violates a second design principle here...
favor composition over inheritance.
posted @
2005-08-11 09:35 Dave 阅读(136) |
评论 (0) |
编辑 收藏
1. can sometimes add a lot of small classes to a design and this occasionally results in a design that's less than straightforward for others to understand.
2. got typing problems: people sometimes take a piece of client code that relies on specific types and introduce decorators without thinking through everything. Now, one great thing about this pattern is that you can usually insert decorators transparently and the client never has to know it's dealing with a decorator:
3. introducing decorators can increase the complexity of the code needed to instantiate the component.Once you've got decorators, you've got to not only instantiate the component, but also wrap it with who knows how many decorators.
posted @
2005-08-11 09:35 Dave 阅读(94) |
评论 (0) |
编辑 收藏
1. Identify the aspects of your application thar vary and separate them from what stays the same.
2. Program to an interface, not an implementation.
3. Favor composition over inheritance.
4. Strive for loosely coupled designs between objects that interface.
5. Classes should be open for extension, but closed for modification.
6. Depend upon abstractions. Do not depend upon concrete classes.
7. Principle of Least Knowledge - talk only to your immediate friends.
8. The Hollywood Principle - Don't call us, we'll call you.
9. A class should have only one reason to change.
posted @
2005-08-11 09:29 Dave 阅读(115) |
评论 (0) |
编辑 收藏
A Pattern is a solution to a problem in a context.
1.The Strategy Pattern:
defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
2.The Observer Pattern:
difine a one-to-many dependency between objects so that when one object changes state, all of its dependents are notified and updated automatically.
3.The Decorator Pattern :
attaches additional responsibilities to an object dynamically.Decorators provide a flexible alternative to subclassing for extending functionality.
4.The Factory Method Pattern:
defines an interface for creating an object, but lets subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
5.The Abstract Factory Patter:
provides an interface for creating families of related or dependent objects without specifying their concrete classes.
6.The Singleton Pattern:
ensures a class has only one instance, and provides a global point of access to it.
7.Command Pattern:
encapsulates a request as an object, thereby letting you parameterize other objects with different requests, queue or log requests, and support undoable operations.
8.The Adapter Pattern:
converts the interface of a class into another interface the clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.
9.The Facade Pattern:
provides a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.
10.The Template Method Pattern:
defines the skeleton of an algorithm in a method, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.
11.The Iterator Pattern:
provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
12.The Composite Pattern:
allows you to composite objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformaly.
13.The State Pattern:
allows an object to alter its behavior when its internal state changes. The object will appear to change its class.
posted @
2005-08-09 17:22 Dave 阅读(145) |
评论 (0) |
编辑 收藏
http://www.infoxa.com/asp/book/view_lb.asp?page=41&lb=&sublb=&px=rq
posted @
2005-08-09 09:39 Dave 阅读(112) |
评论 (0) |
编辑 收藏