Node.js 了解

http://blog.feshine.net/technology/460.html

http://www.infoq.com/cn/articles/nodejs-frameworks

http://sd.csdn.net/a/20101123/282337.html

很火,是口头上火!

我也喜欢它,毕竟是javascript!

  • 服务器端的JavaScript
  • 基于Google的V8创建
  • 事件触发、非阻塞的I/O。 类似于EventMachine或Twisted。
  • CommonJS模块系统。
  • 有8000行C/C++代码, 2000行Javascript代码,14个贡献者。

第三点我很感兴趣,但是不知道怎么回事,因为没用过啊。

------------------------------------------------------------------------------------------

http://fafeng.blogbus.com/logs/120975751.html

    Node.js是构建在JavaScript引擎V8之上的JavaScript环境,它是一个异步事件驱动I/O模型,它能够非常好地安装在Linux, Macintosh和Solaris,通过虚拟机MinGWCygwin(编译和运行方法)它也能运行在其它Unix和Windows平台。

    Node.js的特性

    1. 单线程

    2. 异步

    3. 非阻塞IO

    4. 事件驱动(详见Understanding the node.js event loop

    5. Google V8

 

目前只是看看,最重要的问题是,nodejs太年轻了!

如果能成熟起来,做web应用那是太强了:

1:前后端语言相同!

2:用web的方式思考!

3:很好的性能!

 

其最大的特点我看就是它的性能优势了,而这个特点主要也是得益于非阻塞IO加上事件驱动,看看这篇文章

对集中网络IO操作机制的比较:  http://kazge.com/archives/596.html

 

参考:

http://sd.csdn.net/a/20111102/306771.html 关于node.js语言的讨论

Continue reading Node.js 了解

http大文件上传

大文件上传要注意以下几点:

  • input type=file需要放在form中。
  • form的enctype="multipart/form-data"  ie5下encoding="multipart/form-data"
  • form的method=”post”
  • input type=file需要有name属性
  • form的target指向提交页面,如果是空则会提交本页造成页面刷新,可以使用指向隐藏的iframe来解决。
  • form中的其他非file类型字段是可以得到的,但是url中的参数不可得。
  • 参数顺序与html中input排列顺序相同。

以上通过org.apache.commons.fileupload包验证过,其他形式应该也是支持的。

  • input type=file的值是可以得到的是经过安全处理的值。
  • 基于安全原因,不能使用脚本设置input type=file的值。

参见:http://w3help.org/zh-cn/causes/HF1010

  • 如要实现cancel功能,将提交的iframe的src属性设置为’’即可,这导致提交abort。

Continue reading http大文件上传

【转】软件体系结构:定义及风格

我发现书上完全是照这个文章抄的。原文见 http://www.docin.com/p-23802653.html

软件体系结构:定义及风格

Software Architecture:

Definition, Common Software Architectural Style and more.

撰文 / 曾毅

软件体系结构的引入The beginning of Software Architecture

软件设计自从计算机诞生之日起,就存在着显式或是隐式的危机。而1968年,在Garmish召开的国际软件工程会议上人们迫切地感到了软件危机给计算机软件产业的发展带来的巨大阻力。软件危机的两个最大的问题便是:随着计算机软件技术的日新月异,软件的规模越来越大,软件复杂度越来越高。伴随着这两个问题的日益突出,整个软件系统结构的设计与规格说明便显得比在早期软件开发中占有重要地位的算法选择和计算问题的数据结构更为重要。代码级别的软件复用已经远远不能满足大型软件开发的需求。由此便引入了软件体系结构这一概念。

软件体系结构的定义Definition of Software Architecture

从抽象角度来说,软件体系结构包含对于用于构建系统的元素,元素之间的互操作,指导系统构成的模式以及模式上的约束的描述。大体上说来,一个特定系统风格就是由组件集以及各个组件集之间的交互定义的。这些软件系统风格便可以用在大型系统设计中。

虽然人们在很多年前就认识到了软件体系结构的设计使整个软件开发中的关键元素,但是对于软件体系结构的定义直至今日也没有达成一个共识。以下是在软件体系结构理论发展的若干年中比较有影响力的定义:

Dewayne Perry和A1ex Wolf的定义:软件体系结构是具有一定形式的结构化元素,即组件的集合,包括处理组件、数据组件和连接组件。处理组件负责对数据进行加工,数据组件是被加工的信息,连接组件把体系结构的不同部分组组合连接起来。

这一定义注重区分处理组件、数据组件和连接组件,这一方法在其他的定义和方法中基本上得到保持。

Mary Shaw和David Garlan在Software Architecture: Perspectives on an Emerging Discipline一书中指出:软件体系结构是软件设计过程中的一个层次,这一层次超越计算过程中的算法设计和数据结构设计。体系结构问题包括总体组织和全局控制、通讯协议、同步、数据存取,给设计元素分配特定功能,设计元素的组织,规模和性能,在各设计方案间进行选择等。软件体系结构处理算法与数据结构之上关于整体系统结构设计和描述方面的一些问题,如全局组织和全局控制结构、关于通讯、同步与数据存取的协议,设计组件功能定义,物理分布与合成,设计方案的选择、评估与实现等。

Bass,Ctements和Kazman在Software Architecture in Practice一书中给出如下的定义:一个程序或计算机系统的软件体系结构包括一个或一组软件组件、软件组件的外部的可见特性及其相互关系。其中,“软件外部的可见特性”是指软件组件提供的服务、性能、特性、错误处理、共享资源使用等。

通过对若干定义的学习和研究,我将为软件体系结构下一个这样的定义:软件体系结构为软件系统提供了结构、行为和属性的高级抽象,由构成系统的元素描述、这些元素的相互作用、指导元素集成的模式以及这些模式的约束组成。软件体系结构不仅指定了系统的组织结构和拓扑结构,并且显示了系统需求和构成系统的元素之间的对应关系,提供了一些设计决策的基本原理,是构建于软件系统之上的系统级复用。

软件体系结构的影响Definition of Software Architecture

软件体系结构贯穿于软件研发的整个生命周期内,具有重要的影响。这主要从以下三个方面来进行考察:

(1) 利益相关人员之间的交流:软件体系结构是一种常见的对系统的抽象,代码级别的系统抽象仅仅可以成为程序员的交流工具,而包括程序员在内的绝大多数系统的利益相关人员都借助软件体系结构来进行彼此理解、协商、达成共识或者相互沟通的基础。

(2) 系统设计的前期决策:软件体系结构是我们所开发的软件系统最早期设计决策的体现,而这些早期决策对软件系统的后续开发、部署和维护具有相当重要的影响。这也是能够对所开发系统进行分析的最早时间点。

(3) 可传递的系统级抽象:软件体系结构是关于系统构造以及系统各个元素工作机制的相对较小、却又能够突出反映问题的模型。由于软件系统具有的一些共通特性,这种模型可以在多个系统之间传递,特别是可以应用到具有相似质量属性和功能需求的系统中,并能够促进大规模软件的系统级复用。

常用软件体系结构

Common Software Architectural Style

一个小型的软件可能具有一种软件体系结构,而大型的软件一般由多种软件体系结构组成,软件体系结构没有定性的说只有几种风格,但是经过长期的大型软件设计与分析,人们总结出了一些最为常用的软件体系结构风格,总共有五种,分别是:

数据流风格Data Flow Style

数据流风格的体系结构中,我们可以在系统中找到非常明显的数据流,处理过程通常在数据流的路线上“自顶向下、逐步求精”,并且,处理过程依赖于执行过程,而不是数据到来的顺序。比较有代表性的是批作业序列风格、管道/过滤器风格。

图1:管道/过滤器风格的软件体系结构

在管道/过滤器风格的软件体系结构中,每个组件都有一组输入和输出,组件读输入的数据流,经过内部处理,然后产生输出数据流。这个过程通常通过对输入流的变换及增量计算来完成,所以在输入被完全消费之前,输出便产生了。因此,这里的组件被称为过滤器,这种风格的连接器就象是数据流传输的管道,将一个过滤器的输出传到另一过滤器的输入。此风格特别重要的过滤器必须是独立的实体,它不能与其它的过滤器共享数据,而且一个过滤器不知道它上游和下游的标识。一个管道/过滤器网络输出的正确性并不依赖于过滤器进行增量计算过程的顺序。编译器系统就具备典型的管道系统风格的体系结构。在该系统中,一个阶段(包括词法分析、语法分析、语义分析和代码生成)的输出是另一个阶段的输入。

管道/过滤器风格的软件体系结构具有许多很好的特点:

(1) 使得软组件具有良好的隐蔽性和高内聚、低耦合的特点;

(2) 允许设计者将整个系统的输入/输出行为看成是多个过滤器的行为的简单合成;

(3) 支持软件复用。

(4) 系统维护和增强系统性能简单。新的过滤器可以添加到现有系统中来;旧的可以被改进的过滤器替换掉;

(5) 允许对一些如吞吐量、死锁等属性的分析;

(6) 支持并行执行。每个过滤器是作为一个单独的任务完成,因此可与其它任务并行执行。这比下面将要阐述的一种“主-子程序风格”的单线程操作要灵活得多。

这种系统结构的弱点是:

(1) 通常导致进程成为批处理的结构。这是因为虽然过滤器可增量式地处理数据,但它们是独立的,所以设计者必须将每个过滤器看成一个完整的从输入到输出的转换。

(2) 不适合处理交互的应用。当需要增量地显示改变时,这个问题尤为严重。

(3) 因为在数据传输上没有通用的标准,每个过滤器都增加了解析和合成数据的工作,这样就导致了系统性能下降,并增加了编写过滤器的复杂性。

调用/返回风格的体系结构【Call-and-Return Style

调用/返回风格的体系结构在过去的30年之间占有重要的地位,是大型软件开发中的主流风格的体系结构。这类系统中呈现出比较明显的调用/返回的关系。调用/返回风格在常用软件体系结构风格中内涵是比较丰富的,分为:主-子程序风格,面向对象概念中的对象体系结构风格,以及层次型系统风格三种子风格。

Snap1

图 2:主-子程序风格的体系结构

-子程序风格的体系结构是一种经典的编程范型,主要应用在结构化程序设计当中。这种风格的主要目的是将程序划分为若干个小片段,从而使程序的可更改性大大提高。主-子程序体系结构风格有一定的层次性,主程序位于一层,下面可以再划分一级子程序,二级子程序甚至更多。需要特别注意的是主-子程序体系结构风格是单线程控制的。同一时刻只有一个孩子结点的子程序可以得到父亲结点的控制。总结一下主-子程序体系结构风格的特点:

(1)由于单线程控制,计算的顺序得以保障。

(2)并且有用的计算结果在同一时刻只会产生一个。

(3)单线程的控制可以直接由程序设计语言来支持

(4)分层推理机制:子程序的正确性与它调用的子程序的正确性有关。

对象风格的体系结构:抽象数据类型概念对软件系统有着重要作用,目前软件界已普遍转向使用面向对象系统。这种风格建立在数据抽象和面向对象的基础上,数据的表示方法和它们的相应操作封装在一个抽象数据类型或对象中。这种风格的组件是对象,或者说是抽象数据类型的实例。对象是一种被称作管理者(Manager)的组件,因为它负责保持资源的完整性(例如实现对属性,方法的封装)。对象是通过函数和过程调用来交互的。

 

 

图3:数据抽象和面向对象风格的体系结构

对象风格的体系结构具有以下的特点:

(1)对象抽象使得组件和组件之间的操作以黑箱的方式进行。

(2)封装性使得细节内容对外部环境得以良好的隐藏。对象之间的访问是通过方法调用来实现的。

(3)考虑操作和属性的关联性,封装完成了相关功能和属性的包装,并由对象来对它们进行管理。

(4)使用某个对象提供的服务并不需要知道服务内部是如何实现的。

数据抽象和面向对象风格的体系结构在现代的软件开发中广泛应用。但是,面向对象体系结构也存在着某些问题:

(1)对象之间的耦合度比较紧:为了使一个对象和另一个对象通过过程调用等进行交互,必须知道对象的标识。只要一个对象的标识改变了,就必须修改所有其他明确调用它的对象。

(2)必须修改所有显式调用它的其它对象,并消除由此带来的一些副作用。例如A使用了对象B,C也使用了对象B,那么,C对B的使用所造成的对A的影响可能是不可预测的。

分层风格的体系结构是将系统组织成一个层次结构,每一层为上层提供服务,并作为下层的客户端。在分层风格的体系结构中,一般内部的层只对相邻的层可见。层之间的连接器(conector)通过决定层间如何交互的协议来定义。

图4:分层风格的体系结构

这种风格支持基于可增加抽象层的设计。这样,允许将一个复杂问题分解成一个增量步骤序列的实现。由于每一层最多只影响两层,同时只要给相邻层提供相同的接口,允许每层用不同的方法实现,同样为软件复用提供了强大的支持。

分层风格的体系结构有许多可取的属性:

(1)支持基于抽象程度递增的系统设计:使设计者可以把一个复杂系统按递增的步骤进行分解;

(2)支持功能增强:因为每一层至多和相邻的上下层交互,因此功能的改变最多影响相邻的上下层;

(3)支持复用:只要提供的服务接口定义不变,同一层的不同实现可以交换使用。这样,就可以定义一组标准的接口,而允许各种不同的实现方法。

但是,分层风格的体系结构也有其不足之处:

(1)并不是每个系统都可以很容易地划分为分层风格的体系结构,甚至即使一个系统的逻辑结构是层次化的,出于对系统性能的考虑,系统设计师不得不把一些低级或高级的功能综合起来;

(2)很难找到一个合适的、正确的层次抽象方法。

总结一下调用/返回风格的软件体系结构:这类架构中的组件就是各种不同的操作单元(例如,子程序、对象、层次),而连接器则是这些对象之间的调用关系(例如,主-子程序调用,或者对象的方法以及层次体系结构中的协议)。调用-返回结构的优点在于,容易将大的架构分解为一种层次模型,在较高的层次,隐藏那些比较具体的细节,而在较低的层次,又能够表现出实现细节。在这类体系结构中,调用者和被调用者之间的关系往往比较紧密。在这样的情况下,架构的扩充通常需要被调用者和所有调用者都进行适当的修改。

虚拟机风格的体系结构【Virtual Machine Style

虚拟机风格的体系结构设计的初衷主要是考虑体系结构的可移植性。这种体系结构力图模拟它运行于其上的软件或者硬件的功能。

图5:虚拟机风格的体系结构

这种体系结构在很多场合都有用途:

n 它可以被用于模拟或者测试尚未构建成的软硬件系统,它还可以模拟灾难,(例如飞行模拟器,安全攸关的系统 ,这些在现实生活中测试太过于危险并且牺牲太大。

n 虚拟机的例子有:解释器,基于规则的系统,通用语言处理程序。

我们用解释器作一个例子,通过虚拟机特定模块的解释步骤如下所示:

n 解释引擎从被解释的模块中选择一条指令;

n 基于这条指令,引擎更新虚拟机内部的状态;

n 上述过程反复执行;

由于对程序的中断,查询和在运行时的修改能力,通过虚拟机来执行模块大大提高了其稳定性,但是由于在执行过程中附加了额外的计算量,性能方面必然会受到影响。

在虚拟机结构中,组件是被模拟的机器和实际的机器,而连接器则是一组转换规则,这组转换规则能够在保持被模拟的机器中的虚拟状态和逻辑不变的前提下,将操作转换为实际的机器中能够被理解的操作。

这类架构的突出特点是:

n 在虚拟机器环境中运行的代码不必须了解虚拟机的具体细节。

n 一旦运行环境发生变化,只需要重写虚拟机本身,而不是整个系统。

n 通常虚拟机会限制在其中运行的软件的行为,特别是那些以实现跨平台为目的的虚拟机,如Java虚拟机和.NET CLR。这类虚拟机往往希望虚拟机器的代码完全不了解虚拟机以外的现实世界。这是在灵活性、效率与软件跨平台性之间进行的一种折衷。

n 能够使系统的结构更具层次性,使用虚拟机提供的设施编写的代码,可以不考虑虚 拟机以外的实际环境,而在正确地实现了这种虚拟机的环境中执行。

虚拟机架构的缺点是灵活性略显不足,无法最大限度地发挥操作系统和硬件的性能,在虚拟机中运行的应用程序并不了解实际的硬件和操作系统的特性。

独立组件风格的体系结构【Independent Components Style

独立组件风格的体系结构由很多独立的通过消息交互的过程或者对象组成。

图6:独立组件风格的体系结构

这种软件体系结构通过对各自部分计算的解耦操作来达到易更改的目的。它们之间相互的传输数据,但是不直接控制双方。消息可能传递给:

· 指定的参与项 (交互过程风格);

· 未指定的参与项 使用发布/登陆范型(事件风格) 。

事件系统风格 是独立组件风格的一个子风格。其中的每一个独立组件在它们的相关环境中声明它们希望共享的数据,这个环境便是未指定的参与项。事件系统会充分利用消息管理器(message manager)在消息传递到消息管理器的时候来管理组件之间的交互,和调用组件。组件会注册它们希望提供或者希望收到的信息的类型。

图7: 事件系统风格

随后它们会发送这个注册的类型给消息管理器,这个消息管理器可能是一个对象引用。

通信处理风格也是独立组件风格的一个子风格。这是一个多处理系统。

客户端-服务器风格是一个非常著名的风格。这种风格设计的目标是达到可测量性的需求。

图8:通信处理风格

服务器用于向一个或者多个客户端提供数据服务,这个环境经常与网络连接一起出现。客户端向服务器发出一个请求,服务器同步地或者异步地执行客户端的请求。如果工作是同步的,服务器将返回给客户端数据和客户端控制权,如果是异步的,服务器只返回给客户端数据,因为这个时候服务器有自己的控制线程。

独立组件架构的特点是:

n 系统由松耦合的一些独立运行的计算单元构成,这些单元之间通过消息传递信息。一般情况下,这些独立的计算单元能够自主地完成一些计算任务。

n 消息的发出者通常并不知道谁会接收并处理这些消息,更不了解这些消息是如何被处理的。

n 由于系统基于消息,因此有较好的并发性能,容错性和可伸缩性。

n 独立组件系统中通常不存在比较明显的主-从结构。通常只有一个比较弱的服务器,甚至没有服务器。

仓库风格的体系结构【Data Centered (Repositories) Style

在仓库风格中,有两种不同的组件:中央数据结构(用于说明当前状态),和独立组件(在中央数据存贮上执行),仓库与外组件间的相互作用在系统中会有大的变化。

图9:仓库风格的体系结构

控制原则的选取产生两个主要的子类。若输入流中某类时间触发进程执行的选择,则仓库是一个传统型数据库;系统中的组件通常包括数据存储区,以及与这些存储区进行交流的进程或处理单元,而连接器则是对于存储区的访问。这类系统中,数据处理进程往往并不直接发生联系,它们之间的联系主要是通过共享的数据存储区来完成的。这种现象非常类似于在独立组件架构中的情况。另一方面,若中央数据结构的当前状态触发进程执行的选择,则仓库是一黑板系统。

Blackboard

(Shared data)

KS2

KS3

KS4

KS5

KS6

KS7

KS8

KS1

Computation

Memory

Direct access

图10: 黑板系统体系结构

黑板系统的传统应用是信号处理领域,如语音和模式识别。另一应用是松耦合代理数据共享存取。

仔细观察图4所示,可以发现黑板系统主要由三部分组成:

(1)知识源:知识源中包含独立的、与应用程序相关的知识,知识源之间不直接进行通讯,它们之间的交互只通过黑板来完成。

(2)黑板数据结构:黑板数据是按照与应用程序相关的层次来组织的解决问题的数据,知识源通过不断地改变黑板数据来解决问题。

           (3)控制:控制完全由黑板的状态驱动,黑板状态的改变决定使用的特定知识。

仓库风格的体系结构的优点在于可扩充性比较强,模块间耦合比较松散,便于扩充。

常用软件体系结构风格综合运用实例

Case Study for Common Software Architectural Style

基于OpenGIS规范的Web要素服务软件具有复杂的软件体系结构。这是一套基于面向对象技术构建的地理信息系统综合应用平台。整个的软件环境配置和所开发的系统程序架构如下图所示:是一个层次分明的分层体系结构风格。最底层为数据存储层,存储介质是Oracle 9i数据库。上一层是空间数据库引擎,完成底层元数据的提取,传输和转换。再向上一层是Web服务包装层,完成了Web要素服务的三大功能。三个主要层次之间的连接器便是三层都遵守的数据传输协议。每一层次只与相邻的层次有关,与彼此隔离的层次没有直接关系。

Database(Oracle 9i)

Compress

Web Service Wrapper

GetCapabilities

DescribeFeatureType

GetFeature

SDE Proxy

ArcSDE Client

ArcSDE

Server

ArcSDE Server

Config Info

(XML)

WFS Config Pro

ArcSDE client

Meta Data

GCompress Module

LZSS Module

图11:WFS系统层次体系结构

在Web要素服务软件的功能设计和实现上,三大功能块的设计采用的是面向对象体系结构

Client

(sRequest)

Invoker

execute()

DescribeFeatureType

ExecuteService()

BaseOperation

GetCapabilities

ExecuteService()

GetFeature

ExecuteServiceFT()

图12: WFS系统面向对象体系结构

由于三大功能都有一些基本的操作,所以设计为由BaseOperation基类派生出三大功能类。三大类中封装了各自隐私的数据和操作。各个操作之间的交互通过成员函数进行调用。三大功能类以及基类便是属性和方法的管理者(Manager)。成员函数在整个系统中完成过程调用的工作。

对于整个系统的应用,是一个典型的客户端-服务器风格。WFS服务器提供Server服务,若干个客户端通过Internet向服务器请求数据,服务器并行处理客户端的请求并将处理数据返回给客户端。

结束语Conclusion】

软件体系结构风格为系统级别的软件复用提供了可能。然而,对于应用体系结构风格来说,由于视角的不同,系统设计师有很大的选择空间。要为系统选择或设计某一个体系结构风格,必须根据特定项目的具体特点,进行分析比较后再确定,体系结构风格的使用几乎完全是特化的。随着软件研发技术的不断进步,软件体系结构的五种模式也不能完全代表体系结构的基本构成了,从而诞生了:正交软件体系结构,三层C/S体系结构,C/S与B/S混合软件体系结构等。不同的结构有不同的处理能力的强项和弱点,一个系统的体系结构应该根据实际需要进行选择,以解决实际问题。

参考文献【Bibliography

[1]Len Bass, Paul Clements, Software Architecture in Practice(Second Edition)

[2]Mary Shaw, David Garlan, Software Architecture: Perspectives on an Emerging Discipline

[3] D.Helic & N.Scherbakov, Software Paradigms

参见:

http://www.cnblogs.com/winter-cn/archive/2008/06/01/1211757.html

Continue reading 【转】软件体系结构:定义及风格

享元模式

这个享元翻译的不是很好,让初接触的不明所以。倒不如它的英文flyweight更直观。

这才发现成天使用的Extjs里面的Ext.fly原来就是这种模式!

参见:

--------------------------------------

Ext.fly = El.fly;
/**
* Gets the globally shared flyweight Element, with the passed node as the active element. Do not store a reference to this element -
* the dom node can be overwritten by other code.
* @param {String/HTMLElement} el The dom node or id
* @param {String} named (optional) Allows for creation of named reusable flyweights to
*                                  prevent conflicts (e.g. internally Ext uses "_internal")
* @static
* @return {Element} The shared Element object (or null if no matching element was found)
*/
El.fly = function(el, named){
    named = named || '_global';
    el = Ext.getDom(el);
    if(!el){
        return null;
    }
    if(!El._flyweights[named]){
        El._flyweights[named] = new El.Flyweight();
    }
    El._flyweights[named].dom = el;
    return El._flyweights[named];
};

---------------------------------

El._flyweights = {};
var flyFn = function(){};
flyFn.prototype = El.prototype;
var _cls = new flyFn();

// dom is optional
El.Flyweight = function(dom){
    this.dom = dom;
};

El.Flyweight.prototype = _cls;
El.Flyweight.prototype.isFlyweight = true;

Continue reading 享元模式

设计模式

参见

http://zh.wikipedia.org/wiki/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F_%28%E8%AE%A1%E7%AE%97%E6%9C%BA%29

http://blog.csdn.net/name_110/article/category/911282

http://coolshell.cn/articles/3320.html

 

模式名称描述设计模式》中提及代码大全》中提及[1]
创建型模式
抽象工厂模式

为一个产品族提供了统一的创建接口。当需要这个产品族的某一系列的时候,可以从抽象工厂中选出相应的系列创建一个具体的工厂类。

http://kazge.com/archives/646.html

工厂方法模式

定义一个接口用于创建对象,但是让子类决定初始化哪个类。工厂方法把一个类的初始化下放到子类。

  • java.lang.Proxy#newProxyInstance()
  • java.lang.Object#toString()
生成器模式

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

  • java.lang.StringBuilder#append()
  • java.lang.StringBuffer#append()
惰性初始模式

推迟对象的创建、数据的计算等需要耗费较多资源的操作,只有在第一次访问的时候才执行。

对象池模式通过回收利用对象避免获取和释放资源所需的昂贵成本。
原型模式

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

  • java.lang.Object#clone()
  • java.lang.Cloneable
单例模式

确保一个类只有一个实例,并提供对该实例的全局访问。

java.lang.Runtime#getRuntime()

多例模式确保一个类只有命名的实例,并提供对这些实例的全局访问。
资源获取为初始化通过绑定到合适对象的生命周期来确保资源被适当地释放。
结构型模式
适配器模式

将某个类的接口转换成客户端期望的另一个接口表示。适配器模式可以消除由于接口不匹配所造成的类兼容性问题。

 Snap1

  • java.util.Arrays#asList()
  • javax.swing.JTable(TableModel)
  • java.io.InputStreamReader(InputStream)
  • java.io.OutputStreamWriter(OutputStream)
  • javax.xml.bind.annotation.adapters.XmlAdapter#marshal()
  • javax.xml.bind.annotation.adapters.XmlAdapter#unmarshal()
桥接模式

将一个抽象与实现解耦,以便两者可以独立的变化。 JDBC

组合模式

把多个对象组成树状结构来表示局部与整体,这样用户可以一样的对待单个对象和对象的组合。

UI组件

 Snap2

  • javax.swing.JComponent#add(Component)
  • java.awt.Container#add(Component)
  • java.util.Map#putAll(Map)
  • java.util.List#addAll(Collection)
  • java.util.Set#addAll(Collection)
修饰模式

向某个对象动态地添加更多的功能。修饰模式是除类继承外另一种扩展功能的方法。

 Snap3

  • java.io.BufferedInputStream(InputStream)
  • java.io.DataInputStream(InputStream)
  • java.io.BufferedOutputStream(OutputStream)
  • java.util.zip.ZipOutputStream(OutputStream)
  • java.util.Collections#checked[List|Map|Set|SortedSet|SortedMap]()
外观模式

为子系统中的一组接口提供一个一致的界面, 外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

  • java.lang.Class
  • javax.faces.webapp.FacesServlet

我看不出来这两个的facade模式。一个大颗粒的服务函数是否就可以说是门面模式?

享元

通过共享以便有效的支持大量小颗粒对象。

  • Ext.fly
代理

为其他对象提供一个代理以控制对这个对象的访问。

  • RMI
行为型模式
黑板广义的观察者在系统范围内交流信息,允许多位读者和写者。
责任链

为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它。

javax.servlet.Filter#doFilter()

命令

将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可取消的操作。

  • java.lang.Runnable
  • javax.swing.Action
解释器

给定一个语言, 定义它的文法的一种表示,并定义一个解释器, 该解释器使用该表示来解释语言中的句子。

java.text.Format

迭代器

提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。

  • java.util.Iterator
  • java.util.Enumeration
中介者

包装了一系列对象相互作用的方式,使得这些对象不必相互明显作用,从而使它们可以松散偶合。当某些对象之间的作用发生改变时,不会立即影响其他的一些对象之间的作用,保证这些作用可以彼此独立的变化。

  • java.util.concurrent.ExecutorService#<T> Future<T> submit(Callable<T> task)

让一个复杂的交互变得简单明了,买房者与售房者在中介介入下,是不能直接联系的,双方只会和中介联系。

备忘录

备忘录对象是一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捉住,并外部化,存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。

  • java.io.Serializable
空对象

通过提供默认对象来避免空引用。

  • java.util.Collections#emptyList()
  • java.util.Collections#emptyMap()
  • java.util.Collections#emptySet()
观察者模式

在对象间定义一个一对多的联系性,由此当一个对象改变了状态,所有其他相关的对象会被通知并且自动刷新。

  • java.util.EventListener
规格以布尔形式表示的可重绑定的商业逻辑。
状态

让一个对象在其内部状态改变的时候,其行为也随之改变。状态模式需要对每一个系统可能取得的状态创立一个状态类的子类。当系统的状态变化时,系统便改变所选的子类。

  • java.util.Iterator
策略

定义一个算法的系列,将其各个分装,并且使他们有交互性。策略模式使得算法在用户使用的时候能独立的改变。

  • java.util.Comparator#compare()
模板方法

模板方法模式准备一个抽象类,将部分逻辑以具体方法及具体构造子类的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。先构建一个顶级逻辑框架,而将逻辑的细节留给具体的子类去实现。

jsf中绘制一个组件:

  • renderBegin
  • renderChildren
  • renderEnd
访问者

封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改,接受这个操作的数据结构可以保持不变。访问者模式适用于数据结构相对未定的系统,它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由的演化。

访问者对被访问者结构不熟悉,首先需要被访问者允许它来访问(accept),然后由被访问者领着访问者依次访问内部结构,针对每个结构做出不同操作。

并发型模式
主动对象
阻碍
双重检查锁定
守卫
领导者/追随者
监测对象模式
读写锁
调度
线程池模式
线程特定存储
反应器

Continue reading 设计模式

数据集成模型

数据集成是企业集成的一种方式,数据集成有多种模型:

联邦数据库系统(FDBS)

由半自治数据库系统构成,相互之间分享数据,联盟各数据源之间相互提供访问接口,同时联盟数据库系统可以是集中数据库系统或分布式数据库系统及其他联邦式系统。在这种模式下又分为紧耦合和松耦合两种情况,紧耦合提供统一的访问模式,一般是静态的,在增加数据源上比较困难; 而松耦合则不提供统一的接口,但可以通过统一的语言访问数据源,其中核心的是必须解决所有数据源语义上的问题。

中间件模式

通过统一的全局数据模型来访问异构的数据库、遗留系统、Web 资源等。中间件位于异构数据源系统(数据层) 和应用程序(应用层) 之间,向下协调各数据源系统,向上为访问集成数据的应用提供统一数据模式和数据访问的通用接口。各数据源的应用仍然完成它们的任务,中间件系统则主要集中为异构数据源提供一个高层次检索服务。

数据仓库

是在企业管理和决策中面向主题的、集成的、与时间相关的和不可修改的数据集合。其中,数据被归类为广义的、功能上独立的、没有重叠的主题。这几种方法在一定程度上解决了应用之间的数据共享和互通的问题,但也存在以下的异同:联邦数据库系统主要面向多个数据库系统的集成,其中数据源有可能要映射到每一个数据模式,当集成的系统很大时,对实际开发将带来巨大的困难。

 

    中间件模式是目前比较流行的数据集成方法,它通过在中间层提供一个统一的数据逻辑视图来隐藏底层的数据细节,使得用户可以把集成数据源看为一个统一的整体。这种模型下的关键问题是如何构造这个逻辑视图并使得不同数据源之间能映射到这个中间层。

    数据仓库技术则在另外一个层面上表达数据之间的共享,它主要是为了针对企业某个应用领域提出的一种数据集成方法,也就是我们在上面所提到的面向主题并为企业提供数据挖掘和决策支持的系统。

 

共享数据库 数据交换中心 http://www.doc88.com/p-57941106042.html

关键字:一处写,多处用 对原有数据需要修改模型

Snap1

Snap2

Snap3

参见:

http://news.csdn.net/n/20080515/115959.html

http://www.doc88.com/p-57941106042.html

Continue reading 数据集成模型

extjs TreeNode 隐藏展开图标

TreeNode只有expandable这个配置来决定是否显示展开图标,对于要动态设置是否可见的情况,只有通过样式表来实现:

TreeNode.ui 添加class例如:

trrnode.ui.addClass(‘hide-expicon’);

然后再样式表中加入样式:

.hide-expicon .x-tree-ec-icon {
	visibility: hidden;
}

同理,要显示图标则:

trrnode.ui.removeClass(‘hide-expicon’);

Continue reading extjs TreeNode 隐藏展开图标

hashCode 牛角尖

hashCode有什么用?java doc里面说的很清楚了:

  • 1:在 Java 应用程序执行期间,在同一对象上多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是对象上 equals 比较中所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。(同一对象多次调用hashCode应该是相同的。)
  • 2:如果根据 equals(Object) 方法,两个对象是相等的,那么在两个对象中的每个对象上调用 hashCode 方法都必须生成相同的整数结果。 equals比较相同的对象,hashCode应该相同)
  • 3:以下情况 是必需的:如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么在两个对象中的任一对象上调用 hashCode 方法必定会生成不同的整数结果。但是,程序员应该知道,为不相等的对象生成不同整数结果可以提高哈希表的性能。(这句话的意思是不同的对象,他们的hashCode可以是相同的。)

    对于使用hash来判断的集合来说,还是直接看源码比较清楚,以hashmap来说:

    public V put(K key, V value) {
            if (key == null)
                return putForNullKey(value);
            int hash = hash(key.hashCode());
            int i = indexFor(hash, table.length);
            for (Entry<K,V> e = table[i]; e != null; e = e.next) {
                Object k;
                if (

    e.hash == hash && ((k = e.key) == key || key.equals(k))) {
    V oldValue = e.value;
    e.value = value;
    e.recordAccess(this);
    return oldValue;
    }
    }

    modCount++;
    addEntry(hash, key, value, i);
    return null;
    }

    public V get(Object key) {
            if (key == null)
                return getForNullKey();
            int hash = hash(key.hashCode());
            for (Entry<K,V> e = table[indexFor(hash, table.length)];
                 e != null;
                 e = e.next) {
                Object k;
                if (

    e.hash == hash && ((k = e.key) == key || key.equals(k)))
    return e.value;
    }
    return null;
    }

     

    看清楚了,是先比较hashcode再比较equal,当然,一旦hashcode不同,短路后那么equal就不会判断了。

    这就揭开了我的牛角尖,不同类型的对象hashcode相同怎么办?

    不同类型对象即使hashcode存在偶然相同的可能,equal理论上是应该不同的。在实现hashcode时,只要考虑同一类型中不同即可,不必要做到UUID的级别!

    那么就别把hashcode当UUID使用了!

    Continue reading hashCode 牛角尖

  • Pagination


    Total views.

    © 2013 - 2019. All rights reserved.

    Powered by Hydejack v6.6.1