??xml version="1.0" encoding="utf-8" standalone="yes"?>一区中文字幕电影,9999久久久久,蜜桃999成人看片在线观看http://www.aygfsteel.com/junhong/archive/2006/06/28/55575.htmljunhongjunhongWed, 28 Jun 2006 09:46:00 GMThttp://www.aygfsteel.com/junhong/archive/2006/06/28/55575.htmlhttp://www.aygfsteel.com/junhong/comments/55575.htmlhttp://www.aygfsteel.com/junhong/archive/2006/06/28/55575.html#Feedback0http://www.aygfsteel.com/junhong/comments/commentRss/55575.htmlhttp://www.aygfsteel.com/junhong/services/trackbacks/55575.html阅读全文

junhong 2006-06-28 17:46 发表评论
]]>
Thinking in java reviewhttp://www.aygfsteel.com/junhong/archive/2006/06/27/55384.htmljunhongjunhongTue, 27 Jun 2006 09:40:00 GMThttp://www.aygfsteel.com/junhong/archive/2006/06/27/55384.htmlhttp://www.aygfsteel.com/junhong/comments/55384.htmlhttp://www.aygfsteel.com/junhong/archive/2006/06/27/55384.html#Feedback0http://www.aygfsteel.com/junhong/comments/commentRss/55384.htmlhttp://www.aygfsteel.com/junhong/services/trackbacks/55384.html 1?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">  Java  中所有的 member function 都是动态绑?/span>

2?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">  Java 中所有的对象都是通过 new 来动态?/span>

3?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">  所有的容器 (collection) ?/span> Object array( 对象数组 e.g String []str=new String[10]) 内都包含都是对象?/span> reference

4?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">  ?/span> java 中, java ~译器有责Q产生“将 stack 指针前后Ud“的E序代码Q所?/span> 它必能够完全掌握它所~译的的E序中“存?/span> stack 里头的所有数据的实际大小和存zL间“, 如此一来便会限制程序的Ҏ?/span> ׃q个限制Q尽我们可以将对象?/span> reference 存储?/span> stack 内,但却不能一般的 java 对象攑֜ stack ?/span>
特例Q( primitive types Q?/span>
基本型别会经常被使用Q如果?/span> new 来生此cL,极简单的变量Q会因?/span> new 对象置?/span> heap 之上?/span> 而效率不好。因此对于此cd?/span> java 采取 c/c++ 的方式,也就是不?/span> new 分配器空_而是产生一U所谓的 ”automatic “变量,存于 static ?/span>

5?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">  当你产生某个存储对象的数l,真正产生的是个存?/span> reference 的数l。此数组建立之后Q其中的每一?/span> reference 都会被自动设为某个特D的?/span> null,

6?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">  { String s=new String(“ddd?;} s q个 reference 会在生存I间之外消失无踪Q但是, s 先前所指的那个 String 对象仍然会l占用内?/span>

7?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">  Class 内的基本型别变量都有初|但是在函数内?/span> local variable 是没有初值的

8?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">  Java 中,所有传递的对象的场合,传递的都是对象?/span> reference.

9?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">  Return Q?/span> 说明q个函数q行l束Q返回到其调用函数?/span> Return 2 Q返回一个数 2 l调用者,同时l束本函数的q行?/span>

10?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">              Class 内的 non-static data(state) ?/span> method , 都是和特定的对象l定的,一般情况下Q你的生某个对象,再通过该对象取用其数据和函数。所?/span> non-static 数据 / 函数必须知道他们隶属于哪一个对象,才有办法q行 .static 函数内不能?/span> non-static 数据和函?/span>

11?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">              (object1= = object2 ) 两个对象?/span> reference ?/span> = = 比较得是两个对象的内存的地址。所以我们不能?/span> = = 来测试两个对象的内容是否相等。如果想试对象的内Ҏ否相{,应该使用 equal(), M一个对象都拥有q个函数。不q你自己?/span> class 需?/span> override q个函数Q否则默认的 equal() 函数是还是比较的两个对象的内存地址?/span>
Java
标准E序库中的大多数 class ?/span> override ?/span> equal(), 所以他们都会比较对象的内容是否相等?/span>

12?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">              位运符都是作用于基本正数类型。该q算W主要是针对g~程使用Q我们用得不多,Q?/span>

待箋

 

 



junhong 2006-06-27 17:40 发表评论
]]>
关于输入框中昄双引号和单引?/title><link>http://www.aygfsteel.com/junhong/archive/2006/04/19/42026.html</link><dc:creator>junhong</dc:creator><author>junhong</author><pubDate>Wed, 19 Apr 2006 15:39:00 GMT</pubDate><guid>http://www.aygfsteel.com/junhong/archive/2006/04/19/42026.html</guid><wfw:comment>http://www.aygfsteel.com/junhong/comments/42026.html</wfw:comment><comments>http://www.aygfsteel.com/junhong/archive/2006/04/19/42026.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/junhong/comments/commentRss/42026.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/junhong/services/trackbacks/42026.html</trackback:ping><description><![CDATA[<table align="center" border="0" cellpadding="0" cellspacing="0" width="98%"> <tbody> <tr> <td height="20"> <br /> </td> </tr> <tr> <td bgcolor="#e8e8e8" height="30"> <div align="center"> <font color="#ff0000" size="4"> <strong>关于输入框中昄双引号和单引?/strong> </font> </div> </td> </tr> <tr> <td> <!--内容开?-> 关于输入框中昄双引号和单引? <br /><br />前台昄解决办法: <br />Ҏ一: <br />单引?lt;input type="text" value="'"> <br />双引?lt;input type="text" value='"'> <br />Ҏ? <br />单引?lt;input type="text" value="&#39;"> <br />双引?lt;input type="text" value="&#34;"> <br /><br /><br />从后台读取数据前台显C军_? <br />我们从数据库中读取值到前台昄时应该加入{? <br /><br />JavaScript版本: <br /><br /><% @Language="JavaScript" %> <br /><% <br />function ForamtValue(oStr) <br />{ <br /> switch(typeof(oStr)) <br /> { <br /> case "date" : <br /> //直接toString()转换,可以加入丰富的显C方? <br /> sStr = (new Date(oStr)).toString(); <br /> break; <br /> default : <br /> sStr = String(oStr); <br /> } <br /> sStr = sStr.replace(/\"/g,"&#34;"); //输入框中昄双引号问? <br /> sStr = sStr.replace(/\'/g,"&#39;"); //输入框中昄单引号问? <br /> return sStr; <br />} <br />%> <br /><br /><% <br />//试 <br />var str = "\"灰豆宝宝.net(季节)\""; <br />var str = new Date(); <br />%> <br /><br> <br /><input type="text" value="<%=str%>" style="width:200px">[不能正常昄]<br> <br /><input type="text" value="<%=ForamtValue(str)%>" style="width:200px">[正常昄]<br> <br /><br /><br />VBScript版本: <br /><br /><% @Language="VBScript" %> <br /><% <br />function ForamtValue(oStr) <br /> Select Case VarType(oStr) <br /> Case "vbDate" <br /> '直接toString()转换,可以加入丰富的显C方? <br /> sStr = CDate(oStr) <br /> Case Else <br /> sStr = CStr(oStr) <br /> End Select <br /> sStr = Replace(sStr,"""","&#34;") '输入框中昄双引号问? <br /> sStr = Replace(sStr,"'","&#39;") '输入框中昄单引号问? <br /> ForamtValue = sStr <br />End Function <br />%> <br /><br /><% <br />'试 <br />Dim str <br />str = """'灰豆宝宝.net(季节)'""" <br />%> <br /><br> <br /><input type="text" value="<%=str%>" style="width:200px">[不能正常昄]<br> <br /><input type="text" value="<%=ForamtValue(str)%>" style="width:200px">[正常昄]<br> <br /></td> </tr> </tbody> </table><img src ="http://www.aygfsteel.com/junhong/aggbug/42026.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/junhong/" target="_blank">junhong</a> 2006-04-19 23:39 <a href="http://www.aygfsteel.com/junhong/archive/2006/04/19/42026.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>how to use ant to deply your web applicationhttp://www.aygfsteel.com/junhong/archive/2006/04/19/42008.htmljunhongjunhongWed, 19 Apr 2006 13:41:00 GMThttp://www.aygfsteel.com/junhong/archive/2006/04/19/42008.htmlhttp://www.aygfsteel.com/junhong/comments/42008.htmlhttp://www.aygfsteel.com/junhong/archive/2006/04/19/42008.html#Feedback0http://www.aygfsteel.com/junhong/comments/commentRss/42008.htmlhttp://www.aygfsteel.com/junhong/services/trackbacks/42008.html


First of all, if you develop your application by Eclipse, it means you have had the ant tool and you need not to download the internet.

Projects

A project has three attributes:

Attribute Description Required
name the name of the project. No
default the default target to use when no target is supplied. No; however, since Ant 1.6.0, every project includes an implicit target that contains any and all top-level tasks and/or types. This target will always be executed as part of the project's initialization, even when Ant is run with the -projecthelp option.
basedir the base directory from which all path calculations are done. This attribute might be overridden by setting the "basedir" property beforehand. When this is done, it must be omitted in the project tag. If neither the attribute nor the property have been set, the parent directory of the buildfile will be used. No

Optionally, a description for the project can be provided as a top-level description type).

Each project defines one or more targets. A target is a set of tasks you want to be executed. When starting Ant, you can select which target(s) you want to have executed. When no target is given, the project's default is used.

Targets

A target can depend on other targets. You might have a target for compiling, for example, and a target for creating a distributable. You can only build a distributable when you have compiled first, so the distribute target depends on the compile target. Ant resolves these dependencies.

It should be noted, however, that Ant's Ant tries to execute the targets in the <target name="A"/>
<target name="B" depends="A"/>
<target name="C" depends="B"/>
<target name="D" depends="C,B,A"/>

Suppose we want to execute target D. From its In a chain of dependencies stretching back from a given target such as D above, each target gets executed only once, even when more than one target depends on it. Thus, executing the D target will first result in C being called, which in turn will first call B, which in turn will first call A. After A, then B, then C have executed, execution returns to the dependency list of D, which will not call B and A, since they were already called in process of dependency resolution for C and B respectively as dependencies of D. Had no such dependencies been discovered in processing C and B, B and A would have been executed after C in processing D's dependency list.

A target also has the ability to perform its execution if (or unless) a property has been set. This allows, for example, better control on the building process depending on the state of the system (java version, OS, command-line property defines, etc.). To make a target sense this property, you should add the unless) attribute with the name of the property that the target should react to. Note: Ant will only check whether the property has been set, the value doesn't matter. A property set to the empty string is still an existing property. For example:

						
								<target name="build-module-A" if="module-A-present"/>
						
				
						
								<target name="build-own-fake-module-A" unless="module-A-present"/>
						
				

In the first example, if the module-A-present property is set (again, to any value), the target will not be run.

If no unless attribute is present, the target will always be executed.

Important: the unless attributes only enable or disable the target to which they are attached. They do not control whether or not targets that a conditional target depends upon get executed. In fact, they do not even get evaluated until the target is about to be executed, and all its predecessors have already run.

The optional -projecthelp command-line option. Targets without such a description are deemed internal and will not be listed, unless either the -debug option is used.

It is a good practice to place your tstamp tasks in a so-called initialization target, on which all other targets depend. Make sure that target is always the first one in the depends list of the other targets. In this manual, most initialization targets have the name .

If the depends attribute and the if/unless attribute are set, the depends attribute is executed first.

A target has the following attributes:

Attribute Description Required
name the name of the target. Yes
depends a comma-separated list of names of targets on which this target depends. No
if the name of the property that must be set in order for this target to execute. No
unless the name of the property that must not be set in order for this target to execute. No
description a short description of this target's function. No

A target name can be any alphanumeric string valid in the encoding of the XML file. The empty string "" is in this set, as is comma "," and space " ". Please avoid using these, as they will not be supported in future Ant versions because of all the confusion they cause. IDE support of unusual target names, or any target name containing spaces, varies with the IDE.

Targets beginning with a hyphen such as are valid, and can be used to name targets that should not be called directly from the command line.

Tasks

A task is a piece of code that can be executed.

A task can have multiple attributes (or arguments, if you prefer). The value of an attribute might contain references to a property. These references will be resolved before the task is executed.

Tasks have a common structure:

						
								<nameattribute1="value1" attribute2="value2" ... />
						
				

where name is the name of the task, attributeN is the attribute name, and valueN is the value for this attribute.

There is a set of built-in tasks , along with a number of optional tasks , but it is also very easy to write your own .

All tasks share a task name attribute. The value of this attribute will be used in the logging messages generated by Ant.

Tasks can be assigned an <taskname id="taskID" ... />

where taskname is the name of the task, and taskID is a unique identifier for this task. You can refer to the corresponding task object in scripts or other tasks via this name. For example, in scripts you could do:

						
								<script ... >
task1.setFoo("bar");
</script>

to set the project.getReference("task1").

Note1: If "task1" has not been run yet, then it has not been configured (ie., no attributes have been set), and if it is going to be configured later, anything you've done to the instance may be overwritten.

Note2: Future versions of Ant will most likely not be backward-compatible with this behaviour, since there will likely be no task instances at all, only proxies.

Properties

A project can have a set of properties. These might be set in the buildfile by the property task, or might be set outside Ant. A property has a name and a value; the name is case-sensitive. Properties may be used in the value of task attributes. This is done by placing the property name between "build/classes.

Built-in Properties

Ant provides access to all system properties as if they had been defined using a ${os.name} expands to the name of the operating system.

For a list of system properties see the Javadoc of System.getProperties .

In addition, Ant has some built-in properties:

				
						basedir             the absolute path of the project's basedir (as set
with the basedir attribute of <project>).
ant.file the absolute path of the buildfile.
ant.version the version of Ant
ant.project.name the name of the project that is currently executing;
it is set in the name attribute of <project>.
ant.java.version the JVM version Ant detected; currently it can hold
the values "1.1", "1.2", "1.3", "1.4" and "1.5".

Example Buildfile

				
						<project name="MyProject" default="dist" basedir=".">
<description>
simple example build file
</description>
<!-- set global properties for this build -->
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="dist" location="dist"/>

<target name="init">
<!-- Create the time stamp -->
<tstamp/>
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build}"/>
</target>

<target name="compile" depends="init"
description="compile the source " >
<!-- Compile the java code from ${src} into ${build} -->
<javac srcdir="${src}" destdir="${build}"/>
</target>

<target name="dist" depends="compile"
description="generate the distribution" >
<!-- Create the distribution directory -->
<mkdir dir="${dist}/lib"/>

<!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
<jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/>
</target>

<target name="clean"
description="clean up" >
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
</project>

Notice that we are declaring properties outside any target. As of Ant 1.6 all tasks can be declared outside targets (earlier version only allowed <typedef> and <antcall> for example).

We have given some targets descriptions; this causes the Finally, for this target to work the source in the <javac> task for details.

Token Filters

A project can have a set of tokens that might be automatically expanded if found when a file is copied, when the filtering-copy behavior is selected in the tasks that support this. These might be set in the buildfile by the filter task.

Since this can potentially be a very harmful behavior, the tokens in the files must be of the form @, where token is the token name that is set in the Note: If a token with the format @ is found in a file, but no filter is associated with that token, no changes take place; therefore, no escaping method is available - but as long as you choose appropriate names for your tokens, this should not cause problems.

Warning: If you copy binary files with filtering turned on, you can corrupt the files. This feature should be used with text files only.

Path-like Structures

You can specify CLASSPATH-type references using both "

Wherever path-like values need to be specified, a nested element can be used. This takes the general form of:

				
						    <classpath>
<pathelement path="${classpath}"/>
<pathelement location="lib/helper.jar"/>
</classpath>

The path attribute accepts colon- or semicolon-separated lists of locations. The location attributes should be preferred.

As a shortcut, the path and <classpath>
<pathelement path="${classpath}"/>
</classpath>

can be abbreviated to:

				
						    <classpath path="${classpath}"/>

In addition, DirSet s, FileSet s, and FileList s can be specified via nested <fileset>, and <classpath>
<pathelement path="${classpath}"/>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
<pathelement location="classes"/>
<dirset dir="${build.dir}">
<include name="apps/**/classes"/>
<exclude name="apps/**/*Test*"/>
</dirset>
<filelist refid="third-party_jars"/>
</classpath>

This builds a path that holds the value of lib directory, the classes under the ${build.dir}, except those that have the text If you want to use the same path-like structure for several tasks, you can define them with a References for an example.

A path-like structure can include a reference to another path-like structure via nested <path id="base.path">
<pathelement path="${classpath}"/>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
<pathelement location="classes"/>
</path>

<path id="tests.path">
<path refid="base.path"/>
<pathelement location="testclasses"/>
</path>

The shortcuts previously mentioned for <path>.For example:

				
						
								
								 <path id="base.path">
<pathelement path="${classpath}"/>
</path>

can be written as:

				
						 <path id="base.path" path="${classpath}"/>
				
		
				
						generally, you need not to write your builder.xml file started from scratch. you can just modify the following
part to meet your demand.
				
						<project name="javastep" default="deploy" basedir=".">
				
		
				
						<!-- ===================== Property Definitions =========================== -->
				
		
				
						    <!--
         All properties should be defined in this section.
         Any host-specific properties should be defined
         in the build.properties file.
				
						  In this app, the following properties are defined in build.properties:
				
		
				
						   o  tomcat.home     - the home directory of your Tomcat installation
        o  webapps.home    - the place to copy the war file to deploy it
    -->
				
						  <property file="build.properties" />
 
				
						  <property name="app.home"          value="." />
  <property name="app.name"          value="javastep" />
  <property name="javadoc.pkg.top"   value="hello" />
				
						  <property name="src.home"          value="${app.home}/src"/>
  <property name="lib.home"          value="${app.home}/WebRoot/WEB-INF/lib"/>
 
  <property name="classes.home"       value="${app.home}/WebRoot/WEB-INF/classes/"/>
  <property name="deploy.home"       value="${app.home}/deploy"/>
  <property name="doc.home"          value="${app.home}/doc"/>
  <property name="web.home"          value="${app.home}/WebRoot"/>
				
						  <property name="build.home"        value="${app.home}/build"/>
  <property name="build.classes"     value="${build.home}/WEB-INF/classes"/>
  <property name="build.lib"         value="${build.home}/WEB-INF/lib"/>
				
						<!-- ==================== Compilation Classpath =========================== -->
				
		
				
						    <!--
         This section creates the classpath for compilation.
    -->
				
						  <path id="compile.classpath">
				
		
				
						    <!-- The object files for this application -->
    <pathelement location="${classes.home}"/>
				
						    <!-- The lib files for this application -->
    <fileset dir="${lib.home}">
      <include name="*.jar"/>
      <include name="*.zip"/>
    </fileset>
				
						    <!-- All files/jars that Tomcat makes available -->
				
		
				
						
								
  </path>
				
						
								
<!-- ==================== Build Targets below here========================= -->
				
						
								
<!-- ==================== "help" Target =================================== -->
				
						    <!--
         This is the default ant target executed if no target is specified.
         This helps avoid users just typing 'ant' and running a
         default target that may not do what they are anticipating...
    -->
				
						 <target name="help" >
   <echo message="Please specify a target! [usage: ant &lt;targetname&gt;]" />
   <echo message="Here is a list of possible targets: "/>
   <echo message="  clean-all.....Delete build dir, all .class and war files"/>
   <echo message="  prepare.......Creates directories if required" />
   <echo message="  compile.......Compiles source files" />
   <echo message="  build.........Build war file from .class and other files"/>
   <echo message="  deploy........Copy war file to the webapps directory" />
   <echo message="  javadoc.......Generates javadoc for this application" />
 </target>
				
						<!-- ==================== "clean-all" Target ============================== -->
				
		
				
						   <!--
          This target should clean up any traces of the application
          so that if you run a new build directly after cleaning, all
          files will be replaced with what's current in source control
   -->
				
						 <target name="clean-all" >
    <delete dir="${build.home}"/>
    <delete dir="${classes.home}"/>
    <delete dir="${deploy.home}"/>
				
						    <!-- can't delete directory if Tomcat is running -->
    <delete dir="${webapps.home}/${app.name}" failonerror="false"/>
				
						    <!-- deleting the deployed .war file is fine even if Tomcat is running -->
    <delete dir="${webapps.home}/${app.name}.war" />
				
						    <!-- delete the javadoc -->
    <delete dir="${doc.home}"/>
				
						 </target>
				
		
				
						<!-- ==================== "prepare" Target ================================ -->
				
		
				
						    <!--
          This target is executed prior to any of the later targets
          to make sure the directories exist. It only creates them
          if they need to be created....
          Other, similar, preparation steps can be placed here.
    -->
				
						  <target name="prepare">
				
		
				
						    <echo message="Tomcat Home = ${tomcat.home}" />
    <echo message="webapps Home = ${webapps.home}" />
				
						    <mkdir dir="${classes.home}"/>
    <mkdir dir="${deploy.home}"/>
				
						    <mkdir dir="${doc.home}"/>
    <mkdir dir="${doc.home}/api"/>
				
						    <mkdir dir="${build.home}"/>
    <mkdir dir="${build.home}/WEB-INF" />
    <mkdir dir="${build.home}/WEB-INF/classes" />
    <mkdir dir="${build.home}/WEB-INF/lib" />
				
						  </target>
				
		
				
						<!-- ==================== "compile" Target ================================ -->
				
		
				
						    <!--
          This only compiles java files that are newer
          than their corresponding .class files.
     -->
				
						  <target name="compile" depends="prepare" >
    <javac srcdir="${src.home}" destdir="${classes.home}" debug="yes" >
        <classpath refid="compile.classpath"/>
    </javac>
  </target>
				
						<!-- ==================== "build" Target ================================== -->
				
		
				
						    <!--
          This target builds the war file for the application
          by first building the directory structure of the
          application in ${build.home} and then creating the
          war file using the ant <war> task
     -->
				
						  <target name="build" >
				
		
				
						    <!-- Copy all the webapp content (jsp's, html, tld's, xml, etc. -->
    <!-- Note that this also copies the META-INF directory -->
    <copy    todir="${build.home}">
      <fileset dir="${web.home}"/>
    </copy>
				
						    <!-- Now, copy all the Java class files -->
    <copy    todir="${build.home}/WEB-INF/classes">
      <fileset dir="${classes.home}"/>
    </copy>
				
						    <!-- Now, copy all the properties files, etc that go on the classpath -->
    <copy    todir="${build.home}/WEB-INF/classes">
      <fileset dir="${src.home}">
         <include name="**/*.properties" />
         <include name="**/*.prop" />
      </fileset>
    </copy>
				
						    <!-- Now, copy all the jar files we need -->
    <copy    todir="${build.home}/WEB-INF/lib">
      <fileset dir="${lib.home}" />
    </copy>
				
						    <!-- Create the <war> file -->
    <jar jarfile="${deploy.home}/${app.name}.war"
         basedir="${build.home}"/>
				
						  </target>
				
		
				
						<!-- ==================== "deploy" Target ================================= -->
				
		
				
						    <!--
         This target simply copies the war file from the deploy
         directory into the Tomcat webapp directory.
     -->
				
						  <target name="deploy" depends="build" >
				
		
				
						    <!-- Copy the contents of the build directory -->
    <copy todir="${webapps.home}"  file="${deploy.home}/${app.name}.war" />
				
						  </target>
				
		
				
						<!-- ==================== "doc" Target ==================================== -->
				
		
				
						    <!--
         This task creates javadoc. It is dependent upon only the
         'compile' target so it is not executed in a normal build.
         As a result, the target needs to be run on its own.
    -->
				
						  <target name="javadoc" depends="compile">
      <javadoc sourcepath = "${src.home}"
                  destdir = "${doc.home}/api"
             packagenames = "${javadoc.pkg.top}.*"/>
  </target>
 
<!-- ==================== "test" Target ================================== -->
				
						    <!--
        This task runs all test cases. It invokes each test case individually.
        The "test-all" target is tied back to the "struts-test" target which
        actually runs the tests. This allows other test targets to be created
        in this section while maintaining the ability to run each test target
        individually. All individual test targets should be added to the
        "depends" attribute of the "test-all" target to provide a single
        target that runs all tests.
-->
				
						  <target name="test-all" depends="struts-tests" />
				
		
				
						  <target name="struts-tests" depends="build" >
				
		
				
						      <junit printsummary="yes" >
				
		
				
						          <classpath >
              <pathelement location="${classes.home}"/>
              <pathelement location="${build.home}"/>
              <pathelement location="${build.home}/WEB-INF/classes"/>
              <path refid="compile.classpath"/>
          </classpath>
				
						          <formatter type="plain" />
          <test name="hello.mocktest.TestHelloAction" />
          <test name="hello.mocktest.TestHelloActionMultiple" />
      </junit>
   
  </target>
</project>

 



junhong 2006-04-19 21:41 发表评论
]]>
how to use sitemesh http://www.aygfsteel.com/junhong/archive/2006/04/13/40996.htmljunhongjunhongThu, 13 Apr 2006 15:41:00 GMThttp://www.aygfsteel.com/junhong/archive/2006/04/13/40996.htmlhttp://www.aygfsteel.com/junhong/comments/40996.htmlhttp://www.aygfsteel.com/junhong/archive/2006/04/13/40996.html#Feedback0http://www.aygfsteel.com/junhong/comments/commentRss/40996.htmlhttp://www.aygfsteel.com/junhong/services/trackbacks/40996.htmlCopy sitemesh-2.2.1.jar into [web-app]/WEB-INF/lib.
  • Create the file [web-app]/WEB-INF/decorators.xml that contains the following:

    <decorators>
    </decorators>
  • (Optional) Create the file [web-app]/WEB-INF/sitemesh.xml that contains the following:
    <sitemesh>
        <property name="decorators-file" value="/WEB-INF/decorators.xml" />
        <excludes file="${decorators-file}" />
    
        <page-parsers>
            <parser content-type="text/html"
                class="com.opensymphony.module.sitemesh.parser.FastPageParser" />
            <parser content-type="text/html;charset=ISO-8859-1"
                class="com.opensymphony.module.sitemesh.parser.FastPageParser" />
        </page-parsers>
    
        <decorator-mappers>
            <mapper class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper">
                <param name="config" value="${decorators-file}" />
            </mapper>
        </decorator-mappers>
    </sitemesh>
    
  • Add the following to [web-app]/WEB-INF/web.xml within the <web-app> tag:

    <filter>
        <filter-name>sitemesh</filter-name>
        <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
    </filter>
    
    <filter-mapping>
        <filter-name>sitemesh</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    Decorators are the pages that "decorate" the original, requested page (the page that is handed to the SiteMesh filter from the web container). Most (HTML) decorators are a combination of:
    • meta tags (keywords, description, author)
    • stylesheet (CSS)
    • header
    • navigation
    • footer
    • copyright notice
    First, define what different navigation/layout schemes you need. For example: Do I need a default decorator (a standard one for all pages)? Do I have a special layout for the index page? Is the header needed for my documentation files? Do I need printable version of my website?

    Web Application Structure

    Here is an example structure of a web application. This is not needed for SiteMesh to work.

    /decorators

    Directory containing all decorator files (e.g. main.jsp, printable.jsp).

    /includes

    Directory containing all files to be included into other files (e.g. header.jsp, footer.jsp, copyright.jsp).

    /images

    Directory containing all images (e.g. background.gif, logo.gif).

    /styles

    Directory containing all .CSS styles (e.g. ie4.css, ns4.css).

    /scripts

    Directory containing all scripts (JavaScript, VBScript files).

    Good practices:

    • Define a stylesheet to use in the entire application and include it using this script.
    • Use includes in your decorators (e.g. includes/navigation.jsp, includes/style.jsp).
    • Try not to refer to the absolute root ("/") path. Use <%=request.getContextPath()%>/ instead. This will make life easier when moving your web application under another context path.
    • Making your decorators compatible with multiple browsers (IE, Mozilla, Opera, ...) will (probably) make your entire application (all decorated pages) compatible.
    • Be careful when using frames, because decorators may NOT be applied to frames (FrameSetDecoratorMapper).

    My First Decorator

    Basically, all you need to know is what decorator tags you can use. The title, head and body tags are most used.
    Here is an example of a decorator (save it as /decorators/main.jsp):

    1: <%--
    2: % This is the main decorator for all SOMECOMPANY INTRANET pages.
    3: % It includes standard caching, style sheet, header, footer and copyright notice.
    4: --%>
    5: <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %>
    6: <%@ include file="7: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    8: <html>
    9: <head>
    10: <title><decorator:title default="INTRANET" /></title>
    11: <decorator:head />
    12: <%@ include file="

    13: </head>
    14: <body bgcolor="#FFFFFF" background="<%=request.getContextPath()%>/images/bg.gif">
    15: <script type="text/javascript">window.status = "Loading: <decorator:title default="INTRANET" />...";</script>
    16: <%@ include file="/includes/header.jsp"%>
    17: <table width="100%" border="0" cellspacing="0" cellpadding="0">
    18: <tr>
    19: <td height="20" nowrap> </td>
    20: </tr>
    21: <tr>
    22: <td width="1%" nowrap> </td>
    23: <td width="16%" valign="top" nowrap>
    23: <script type="text/javascript">window.status = "Loading: Navigation...";</script>
    24: <%@ include file="/includes/navigation.jsp" %>
    25: </td>
    26: <td width="2%" nowrap> </td>
    27: <td valign="top">
    28: <br>
    29: <script type="text/javascript">window.status = "Loading: Document body...";</script>
    30: <div class="docBody"><decorator:body /></div>
    31: </td>
    32: <td width="1%" nowrap> </td>
    33: </tr>
    34: </table>
    35: <br>
    36: <%@ include file="/includes/footer.jsp" %>
    37: <%@ include file="/includes/copyright.jsp" %>
    38: <script type="text/javascript">window.status = "Done";</script>
    39: </body>
    40: </html>

    Now open WEB-INF/decorators.xml with your favorite editor and let SiteMesh know there is a decorator (with a mapping):

    <decorators defaultdir="/decorators">
        <decorator name="main" page="main.jsp">
              <pattern>/*</pattern>
        </decorator>
    </decorators>
    

    Now deploy the web application, go to the welcome page, and the main decorator will be applied.

  • When a page has been parsed, it then has to be mapped to a decorator. This mapping is performed by a chain of DecoratorMappers (referred to as mappers from here on).

    For each request, the first mapper in the chain is asked which decorator should be used. It is passed across a reference to the Page object and HttpServletRequest. It returns either a Decorator object, if it knows which decorator to be used, or null. If null is returned, the next mapper in the chain is queried. This whole process is repeated until there are no more mappers in the chain, or one of the mappers returns a valid decorator. If no mappers return a decorator, the page is not decorated at all and served in its original state.

    This way the mappers are chained together and queried is known as the Chain of Responsibility design pattern.

    Examples of mappers:

    • Determine decorator based on path of requested page.
    • Use different decorators based on time, locale or browser.
    • Use simplified decorators for search-engine robots.
    • Switch decorators based on a URL parameter, request attribute or meta-tag.
    • Use custom decorators based on user's saved settings...

    The main implementation of DecoratorMapper is ConfigDecoratorMapper which reads the decorators and mappings from /WEB-INF/decorators.xml. The appropriate decorator is then applied depending on the URL pattern.

    DecoratorMappers are simple to write and the distribution includes some samples that demonstrate how to write them and how flexible they can be. These are:

    AgentDecoratorMapper Can determine the user-agent (i.e. web-browser) requesting a page, and map to a suitable Decorator.
    ConfigDecoratorMapper Default implementation of DecoratorMapper. Reads decorators and mappings from the config property (default '/WEB- INF/decorators.xml').
    CookieDecoratorMapper Will map a suitable decorator based on a cookie value.
    EnvEntryDecoratorMapper Allows the reference to a web-app environment entry for the decorator name, and falls back to ConfigDecoratorMapper's behavior if no matching environment entry is found.
    FileDecoratorMapper Will treat the name of the decorator as a file-name to use (in the context of the web-app).
    FrameSetDecoratorMapper Will use the specified decorator when the Page is an instance of HTMLPage and isFrameSet() returns true. The name of this decorator should be supplied in the decorator property - if no decorator property is supplied, no decorator is applied to frame based pages.
    InlineDecoratorMapper Used to determine the correct Decorator when using inline decorators.
    LanguageDecoratorMapper Can determine the preferred language set in the browser requesting a page, and map to a suitable Decorator (using the "Accept-Language" HTTP header).
    PageDecoratorMapper The actual Page determines the Decorator to be used.

    The 'meta.decorator' and 'decorator' properties of the page are accessed and if any of them contain the name of a valid Decorator, that Decorator shall be applied.

    ParameterDecoratorMapper Will choose the decorator based on request parameters.

    The ParameterDecoratorMapper is configured via three properties.

    decorator.parameter - the parameter which contains the name of the decorator which will be mapped. The default is "decorator".

    For example if decorator.parameter is "foobar" then myurl.jsp?foobar=mydecorator will map to the decorator named "mydecorator".

    You can also supply an optional 'confirmation parameter'. The decorator will only be mapped if the parameter named parameter.name is in the request URI and the value of that parameter is equal to the parameter.value property.

    For example assuming parameter.name=confirm and parameter.value=true the URI myurl.jsp?decorator=mydecorator&confirm=true will map the decorator mydecorator. where as the URIs myurl.jsp?decorator=mydecorator and myurl.jsp?decorator=mydecorator&confirm=false will not return any decorator.

    SessionDecoratorMapper

    Will look at a session attribute to find the name of an appropriate decorator to use. If the session attribute is present, the mapper will not do anything and allow the next mapper in the chain to select a decorator.

    By default, it will look at the 'decorator' session attribute, however this can be overriden by configuring the mapper with a 'decorator.parameter' property.

    PrintableDecoratorMapper Will check to see whether 'printable=true' is supplied as a request parameter and if so, use the specified decorator instead. The name of this decorator should be supplied in the decorator property.
    RobotDecoratorMapper Will use the specified decorator when the requester is identified as a robot (also known as spider, crawler, ferret) of a search engine. The name of this decorator should be supplied in the decorator property.

    An example of a custom DecoratorMapper could be one that displays different Decorators based on time (e.g. morning, afternoon, Christmas, etc).

    Custom mapper configuration

    To be able to specify which mappers will be applied to a request, create the file [web-app]/WEB-INF/sitemesh.xml that contains the following:

    <sitemesh>
        <property name="decorators-file" value="/WEB-INF/decorators.xml" />
        <excludes file="${decorators-file}" />
    
        <page-parsers>
            <parser content-type="text/html"
                class="com.opensymphony.module.sitemesh.parser.FastPageParser" />
            <parser content-type="text/html;charset=ISO-8859-1"
                class="com.opensymphony.module.sitemesh.parser.FastPageParser" />
        </page-parsers>
    
        <decorator-mappers>
            <mapper class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper">
                <param name="config" value="${decorators-file}" />
            </mapper>
        </decorator-mappers>
    </sitemesh>
    

    In this example, the only mapper that will be applied is the ConfigDecoratorMapper, and that will only be applied to responses of type text/html or text/html;charset=ISO-8859-1. Responses of any other content type (eg image/gif) will be ignored by Sitemesh. Additionally, any files that match a pattern specified in the excludes file (in this case '/WEB-INF/decorators.xml') will not be touched by Sitemesh.

    The excludes file points to an XML file that contains an <excludes /> block similar to the following:

    <decorators>
        <excludes>
            <pattern>/plainPage.jsp</pattern>
            <pattern>/plain/*.jsp</pattern>
        </excludes>
    </decorators>
    

    The above example would prevent /plainPage.jsp and any JSP pages in the /plain directory from being decorated. (Note that the pattern matching follows exactly the same rules as the decorator mappings used by the ConfigDecoratorMapper.)

    Typically the <excludes /> block is just added at the start of the decorators.xml file, however this is not a requirement and any other XML file can be specified instead by changing the excludes file specified in sitemesh.xml. This might be useful if for example the ConfigDecoratorMapper is not being used in your deployment.

    Note that preventing pages from being decorated by adding them to the excludes list superceeds, and is a better approach than, the old method of mapping the pages to a non-existent decorator. This is because when pages were mapped to a non-existent decorator they were still buffered internally by Sitemesh. By using the exclude list Sitemesh will not let the request pass straight through to the servlet container without any buffering.

    Default mapper configuration

    If sitemesh.xml is not found in the WEB-INF dir, the default mapper configuration will be used. The default mapper configuration is defined in sitemesh-default.xml (packaged inside the jar) and consists of the following mappers:

    • PageDecoratorMapper
    • FrameSetDecoratorMapper
    • PrintableDecoratorMapper
    • FileDecoratorMapper
    • ConfigDecoratorMapper

    By default only content of type text/html will be decorated by Sitemesh.



    for more detail, please refer to http://www.opensymphony.com/sitemesh/dm.html



  • junhong 2006-04-13 23:41 发表评论
    ]]>
    Design Pattern with java (part three)http://www.aygfsteel.com/junhong/archive/2006/04/10/40347.htmljunhongjunhongMon, 10 Apr 2006 15:51:00 GMThttp://www.aygfsteel.com/junhong/archive/2006/04/10/40347.htmlhttp://www.aygfsteel.com/junhong/comments/40347.htmlhttp://www.aygfsteel.com/junhong/archive/2006/04/10/40347.html#Feedback0http://www.aygfsteel.com/junhong/comments/commentRss/40347.htmlhttp://www.aygfsteel.com/junhong/services/trackbacks/40347.htmlSpecialized creation


    1. Prototype
      Objects are created by cloning a prototypical instance.
    2. Builder
      The goal of builder is to separate the construction from the “representation,?to allow multiple
      different representations. The construction process stays the same, but the resulting object
      has different possible representations. GoF points out that the main difference with Abstract
      Factory is that a Builder creates the object step-by-step, so the fact that the creation process is
      spread out in time seems to be important. In addition, it seems that the “director?gets a
      stream of pieces that it passes to the Builder, and each piece is used to perform one of the
      steps in the build process.
      One example given in GoF is that of a text format converter. The incoming format is RTF, and
      once it is parsed the directives are passed to the text converter, which may be implemented in
      different ways depending on whether the resulting format is ASCII, TeX, or a “GUI Text
      Widget.?Although the resulting “object?(the entire converted text file) is created over time, if
      you consider the conversion of each RTF directive to be an object, this feels to me a little more
      like Bridge, because the specific types of converters extend the interface of the base class.
      Also, the general solution to the problem would allow multiple readers on the “front end?and
      multiple converters on the “back end,?which is a primary characteristic of Bridge.
      To me, the fact that Builder has multiple steps in creating an object, and those steps are
      accessed externally to the Builder object, is the essence of what distinguishes it (structurally,
      anyway) from a regular factory. However, GoF emphasizes that you’re able to create different
      representations using the same process. They never define exactly what they mean by
      representation. (Does the “representation?involve an object that is too large? Would the need
      for Builder vanish if the representation was broken into smaller objects?)
      The other example in GoF creates a maze object and adds rooms within the maze and doors
      within the rooms. Thus it is a multistep process, but alas, the different “representations?are
      the “Standard?and “Complex?mazes ?not really different kinds of mazes, but instead
      different complexity. I think I would have tried to create one maze builder that could handle

      arbitrarily complex mazes. The final variation of the maze builder is something that doesn’t
      create mazes at all, but instead counts the rooms in an existing maze.
      Neither the RTF converter nor the Mazebuilder example makes an overwhelmingly
      compelling case for Builder. Readers have suggested that the output of the Sax XML parser,
      and standard compiler parsers, might naturally be fed into a Builder.
      Here’s an example that may be a little more compelling, or at least give more of an idea of
      what Builder is trying to do. Media may be constructed into different representations, in this
      case books, magazines and web sites. The example argues that the steps involved are the
      same, and so can be abstracted into the director class.
      //: builder:BuildMedia.java
      // Example of the Builder pattern
      package builder;
      import java.util.*;
      import junit.framework.*;
      // Different "representations" of media:
      class Media extends ArrayList {}
      class Book extends Media {}
      class Magazine extends Media {}
      class WebSite extends Media {}
      // ... contain different kinds of media items:
      class MediaItem {
      private String s;
      public MediaItem(String s) { this.s = s; }
      public String toString() { return s; }
      }
      class Chapter extends MediaItem {
      public Chapter(String s) { super(s); }
      }
      class Article extends MediaItem {
      public Article(String s) { super(s); }
      }
      class WebItem extends MediaItem {
      public WebItem(String s) { super(s); }
      }
      // ... but use the same basic construction steps:
      class MediaBuilder {
      public void buildBase() {}
      public void addMediaItem(MediaItem item) {}
      public Media getFinishedMedia() { return null; }
      }
      class BookBuilder extends MediaBuilder {
      private Book b;
      public void buildBase() {
      System.out.println("Building book framework");
      b = new Book();
      }
      public void addMediaItem(MediaItem chapter) {
      System.out.println("Adding chapter " + chapter);
      b.add(chapter);
      }
      public Media getFinishedMedia() { return b; }
      }
      class MagazineBuilder extends MediaBuilder {

      private Magazine m;
      public void buildBase() {
      System.out.println("Building magazine framework");
      m = new Magazine();
      }
      public void addMediaItem(MediaItem article) {
      System.out.println("Adding article " + article);
      m.add(article);
      }
      public Media getFinishedMedia() { return m; }
      }
      class WebSiteBuilder extends MediaBuilder {
      private WebSite w;
      public void buildBase() {
      System.out.println("Building web site framework");
      w = new WebSite();
      }
      public void addMediaItem(MediaItem webItem) {
      System.out.println("Adding web item " + webItem);
      w.add(webItem);
      }
      public Media getFinishedMedia() { return w; }
      }
      class MediaDirector { // a.k.a. "Context"
      private MediaBuilder mb;
      public MediaDirector(MediaBuilder mb) {
      this.mb = mb; // Strategy-ish
      }
      public Media produceMedia(List input) {
      mb.buildBase();
      for(Iterator it = input.iterator(); it.hasNext();)
      mb.addMediaItem((MediaItem)it.next());
      return mb.getFinishedMedia();
      }
      };
      public class BuildMedia extends TestCase {
      private List input = Arrays.asList(new MediaItem[] {
      new MediaItem("item1"), new MediaItem("item2"),
      new MediaItem("item3"), new MediaItem("item4"),
      });
      public void testBook() {
      MediaDirector buildBook =
      new MediaDirector(new BookBuilder());
      Media book = buildBook.produceMedia(input);
      String result = "book: " + book;
      System.out.println(result);
      assertEquals(result,
      "book: [item1, item2, item3, item4]");
      }
      public void testMagazine() {
      MediaDirector buildMagazine =
      new MediaDirector(new MagazineBuilder());
      Media magazine = buildMagazine.produceMedia(input);
      String result = "magazine: " + magazine;
      System.out.println(result);
      assertEquals(result,
      "magazine: [item1, item2, item3, item4]");
      }

      public void testWebSite() {
      MediaDirector buildWebSite =
      new MediaDirector(new WebSiteBuilder());
      Media webSite = buildWebSite.produceMedia(input);
      String result = "web site: " + webSite;
      System.out.println(result);
      assertEquals(result,
      "web site: [item1, item2, item3, item4]");
      }
      public static void main(String[] args) {
      junit.textui.TestRunner.run(BuildMedia.class);
      }
      } ///:~



    junhong 2006-04-10 23:51 发表评论
    ]]>
    Design Pattern with java (part two) http://www.aygfsteel.com/junhong/archive/2006/04/10/40343.htmljunhongjunhongMon, 10 Apr 2006 15:23:00 GMThttp://www.aygfsteel.com/junhong/archive/2006/04/10/40343.htmlhttp://www.aygfsteel.com/junhong/comments/40343.htmlhttp://www.aygfsteel.com/junhong/archive/2006/04/10/40343.html#Feedback0http://www.aygfsteel.com/junhong/comments/commentRss/40343.htmlhttp://www.aygfsteel.com/junhong/services/trackbacks/40343.html Encapsulating creation


    Although only the Simple Factory Method is a true singleton, you’ll find that each specify
    factory class in the more general types of factories will only have a single instance.
    1. Simple Factory method
      One approach is to make the factory a static method of the base class:
      //: factory:shapefact1:ShapeFactory1.java
      // A simple static factory method.
      package factory.shapefact1;
      import java.util.*;
      import junit.framework.*;
      abstract class Shape {
      public abstract void draw();
      public abstract void erase();
      public static Shape factory(String type) {
      if(type.equals("Circle")) return new Circle();
      if(type.equals("Square")) return new Square();
      throw new RuntimeException(
      "Bad shape creation: " + type);
      }
      }
      class Circle extends Shape {Circle() {} // Package-access constructor
      public void draw() {
      System.out.println("Circle.draw");
      }
      public void erase() {
      System.out.println("Circle.erase");
      }
      }
      class Square extends Shape {
      Square() {} // Package-access constructor
      public void draw() {
      System.out.println("Square.draw");
      }
      public void erase() {
      System.out.println("Square.erase");
      }
      }
      public class ShapeFactory1 extends TestCase {
      String shlist[] = { "Circle", "Square",
      "Square", "Circle", "Circle", "Square" };
      List shapes = new ArrayList();
      public void test() {
      Iterator it = Arrays.asList(shlist).iterator();
      while(it.hasNext())
      shapes.add(Shape.factory((String)it.next()));
      it = shapes.iterator();
      while(it.hasNext()) {
      Shape s = (Shape)it.next();
      s.draw();
      s.erase();
      }
      }
      public static void main(String args[]) {
      junit.textui.TestRunner.run(ShapeFactory1.class);
      }
      } ///:~
      To encourage creation to only happen in the factory( ), the constructors for the specific
      types of Shape are give package access, so factory( ) has access to the constructors but they
      are not available outside the package.
    2. Polymorphic factories
      different types of factories can be subclassed from the basic factory,for example
      interface Shape {
      void draw();
      void erase();
      }
      abstract class ShapeFactory {
      protected abstract Shape create();
      private static Map factories = new HashMap();
      public static void
      addFactory(String id, ShapeFactory f) {
      factories.put(id, f);
      }
      // A Template Method:
      public static final
      Shape createShape(String id) {
      if(!factories.containsKey(id)) {
      try {
      // Load dynamically
      Class.forName("factory.shapefact2." + id);
      } catch(ClassNotFoundException e) {
      throw new RuntimeException(
      "Bad shape creation: " + id);
      }
      // See if it was put in:
      if(!factories.containsKey(id))
      throw new RuntimeException(
      "Bad shape creation: " + id);
      }
      return
      ((ShapeFactory)factories.get(id)).create();
      }
      }
      class Circle implements Shape {
      private Circle() {}
      public void draw() {
      System.out.println("Circle.draw");
      }
      public void erase() {
      System.out.println("Circle.erase");
      }
      private static class Factory
      extends ShapeFactory {
      protected Shape create() {
      return new Circle();
      }
      }
      static {
      ShapeFactory.addFactory(
      "Circle", new Factory());
      }
      }
      .......
    3. Abstract factories
      The Abstract Factory pattern looks like the factory objects we’ve seen previously, with not
      one but several factory methods. Each of the factory methods creates a different kind of
      object. The idea is that at the point of creation of the factory object, you decide how all the
      objects created by that factory will be used.
      As another example suppose you are creating a general-purpose gaming environment and you
      want to be able to support different types of games
      interface Obstacle {
      void action();
      }
      interface Player {
      void interactWith(Obstacle o);
      }
      class Kitty implements Player {
      public void interactWith(Obstacle ob) {
      System.out.print("Kitty has encountered a ");
      ob.action();
      }
      }
      class KungFuGuy implements Player {
      public void interactWith(Obstacle ob) {
      System.out.print("KungFuGuy now battles a ");
      ob.action();
      }
      }
      class Puzzle implements Obstacle {
      public void action() {
      System.out.println("Puzzle");
      }
      }
      class NastyWeapon implements Obstacle {
      public void action() {
      System.out.println("NastyWeapon");
      }
      }
      // The Abstract Factory:
      interface GameElementFactory {Player makePlayer();
      Obstacle makeObstacle();
      }
      // Concrete factories:
      class KittiesAndPuzzles
      implements GameElementFactory {
      public Player makePlayer() {
      return new Kitty();
      }
      public Obstacle makeObstacle() {
      return new Puzzle();
      }
      }
      class KillAndDismember
      implements GameElementFactory {
      public Player makePlayer() {
      return new KungFuGuy();
      }
      public Obstacle makeObstacle() {
      return new NastyWeapon();
      }
      }
      class GameEnvironment {
      private GameElementFactory gef;
      private Player p;
      private Obstacle ob;
      public GameEnvironment(
      GameElementFactory factory) {
      gef = factory;
      p = factory.makePlayer();
      ob = factory.makeObstacle();
      }
      public void play() { p.interactWith(ob); }
      }
      public class Games extends TestCase {
      GameElementFactory
      kp = new KittiesAndPuzzles(),
      kd = new KillAndDismember();
      GameEnvironment
      g1 = new GameEnvironment(kp),
      g2 = new GameEnvironment(kd);
      // These just ensure no exceptions are thrown:
      public void test1() { g1.play(); }
      public void test2() { g2.play(); }
      public static void main(String args[]) {
      junit.textui.TestRunner.run(Games.class);
      }
      } ///:~
      In this environment, Player objects interact with Obstacle objects, but there are different
      types of players and obstacles depending on what kind of game you’re playing. You determine
      the kind of game by choosing a particular GameElementFactory, and then the
      GameEnvironment controls the setup and play of the game. In this example, the setup and
      play is very simple, but those activities (the initial conditions and the state change) can
      determine much of the game’s outcome. Here, GameEnvironment is not designed to be
      inherited, although it could very possibly make sense to do that.


    junhong 2006-04-10 23:23 发表评论
    ]]>
    Design Pattern with java (part one)http://www.aygfsteel.com/junhong/archive/2006/04/09/40108.htmljunhongjunhongSun, 09 Apr 2006 09:15:00 GMThttp://www.aygfsteel.com/junhong/archive/2006/04/09/40108.htmlhttp://www.aygfsteel.com/junhong/comments/40108.htmlhttp://www.aygfsteel.com/junhong/archive/2006/04/09/40108.html#Feedback0http://www.aygfsteel.com/junhong/comments/commentRss/40108.htmlhttp://www.aygfsteel.com/junhong/services/trackbacks/40108.html
  • Messager
    The most trivial of these is the messenger, which simply packages information into an object
    to be passed around, instead of passing all the pieces around separately. Note that without the
    messenger, the code for translate() would be much more confusing to read:
  • Collecting Parameter
    Messenger’s big brother is the collecting parameter, whose job is to capture information from
    the method to which it is passed. Generally, this is used when the collecting parameter is
    passed to multiple methods, so it’s like a bee collecting pollen.
    A container makes an especially useful collecting parameter, since it is already set up to
    dynamically add objects.
  • Object quantity:Singleton and object pool
    Singleton:The key to creating a singleton is to prevent the client programmer from having any way to
    create an object except the ways you provide. You must make all constructors private, and
    you must create at least one constructor to prevent the compiler from synthesizing a default
    constructor for you (which it will create using package access).
  • Object pool:If this is an issue, you can create a solution involving a check-out
    and check-in of the shared objects. see the following example
    //: singleton:PoolManager.java
    package singleton;
    import java.util.*;
    public class PoolManager {
    private static class PoolItem {
    boolean inUse = false;
    Object item;
    PoolItem(Object item) { this.item = item; }
    }
    private ArrayList items = new ArrayList();
    public void add(Object item) {
    items.add(new PoolItem(item));
    }
    static class EmptyPoolException extends Exception {}
    public Object get() throws EmptyPoolException {
    for(int i = 0; i < items.size(); i++) {
    PoolItem pitem = (PoolItem)items.get(i);
    if(pitem.inUse == false) {
    pitem.inUse = true;
    return pitem.item;
    }
    }
    // Fail early:
    throw new EmptyPoolException();
    // return null; // Delayed failure
    }
    public void release(Object item) {
    for(int i = 0; i < items.size(); i++) {
    PoolItem pitem = (PoolItem)items.get(i);
    if(item == pitem.item) {
    pitem.inUse = false;
    return;
    }
    }
    throw new RuntimeException(item + " not found");
    }
    } ///:~
    //: singleton:ConnectionPoolDemo.java
    package singleton;
    import junit.framework.*;
    interface Connection {
    Object get();
    void set(Object x);
    }
    class ConnectionImplementation implements Connection {
    public Object get() { return null; }
    public void set(Object s) {}
    }
    class ConnectionPool { // A singleton
    private static PoolManager pool = new PoolManager();
    public static void addConnections(int number) {
    17 z 157
    for(int i = 0; i < number; i++)
    pool.add(new ConnectionImplementation());
    }
    public static Connection getConnection()
    throws PoolManager.EmptyPoolException {
    return (Connection)pool.get();
    }
    public static void releaseConnection(Connection c) {
    pool.release(c);
    }
    }
    public class ConnectionPoolDemo extends TestCase {
    static {
    ConnectionPool.addConnections(5);
    }
    public void test() {
    Connection c = null;
    try {
    c = ConnectionPool.getConnection();
    } catch (PoolManager.EmptyPoolException e) {
    throw new RuntimeException(e);
    }
    c.set(new Object());
    c.get();
    ConnectionPool.releaseConnection(c);
    }
    public void test2() {
    Connection c = null;
    try {
    c = ConnectionPool.getConnection();
    } catch (PoolManager.EmptyPoolException e) {
    throw new RuntimeException(e);
    }
    c.set(new Object());
    c.get();
    ConnectionPool.releaseConnection(c);
    }
    public static void main(String args[]) {
    junit.textui.TestRunner.run(ConnectionPoolDemo.class);
    }
    } ///:~
  • Object decoupling:Both Proxy and State provide a surrogate class that you use in your code; the real class that
    does the work is hidden behind this surrogate class.When you call a method in the surrogate,
    it simply turns around and calls the method in the implementing class. These two patterns are
    so similar that the Proxy is simply a special case of State.

    The basic idea is simple: from a base class, the surrogate is derived along with the class or
    classes that provide the actual implementation:
    thinking in patterns with Java.bmp
    When a surrogate object is created, it is given an implementation to which to send all of the
    method calls.
    Structurally, the difference between Proxy and State is simple: a Proxy has only one
    implementation, while State has more than one. The application of the patterns is considered
    (in Design Patterns) to be distinct: Proxy is used to control access to its implementation,
    while State allows you to change the implementation dynamically. However, if you expand
    your notion of “controlling access to implementation?then the two fit neatly together.
  • State: changing object behavior
    The State pattern switches from one implementation to another during the lifetime of the
    surrogate, in order to produce different behavior from the same method call(s). It’s a way to
    improve the implementation of your code when you seem to be doing a lot of testing inside
    each of your methods before deciding what to do for that method. For example, the fairy tale
    of the frog-prince contains an object (the creature) that behaves differently depending on
    what state it’s in. You could implement this using a boolean that you test:
  • Factoring commonality
    Applying the “once and only once?principle produces the most basic
    pattern of putting code that changes into a method.
  • Strategy: choosing the algorithm at run-time
    Strategy also adds a “Context?which can be a surrogate class that controls the selection and
    use of the particular strategy object—just like State!
    thinking in patterns with Java.bmp
  • Policy: generalized strategy
    Although GoF says that Policy is just another name for strategy, their use of Strategy
    implicitly assumes a single method in the strategy object ?that you’ve broken out your
    changing algorithm as a single piece of code.
    Others[6] use Policy to mean an object that has multiple methods that may vary
    independently from class to class. This gives more flexibility than being restricted to a single
    method.
    It also seems generally useful to distinguish Strategies with single methods from Policies with
    multiple methods
  • Template method
    An important characteristic of the Template Method is that it is defined in the base class and
    cannot be changed. It's sometimes a private method but it’s virtually always final. It calls
    other base-class methods (the ones you override) in order to do its job, but it is usually called
    only as part of an initialization process (and thus the client programmer isn’t necessarily able
    to call it directly).
    E.g
    abstract class ApplicationFramework {
    public ApplicationFramework() {
    templateMethod(); // Dangerous!
    }
    abstract void customize1();
    abstract void customize2();
    final void templateMethod() {
    for(int i = 0; i < 5; i++) {
    customize1();
    customize2();
    }
    }
    }
    // Create a new "application":
    class MyApp extends ApplicationFramework {
    void customize1() {
    System.out.print("Hello ");
    }
    void customize2() {
    System.out.println("World!");
    }
    }





  • junhong 2006-04-09 17:15 发表评论
    ]]>
    本h写的分页的标{,?net中的datagrid标签怼Q只需要设|几个属性就可以实现分页功能?/title><link>http://www.aygfsteel.com/junhong/archive/2006/03/07/33960.html</link><dc:creator>junhong</dc:creator><author>junhong</author><pubDate>Tue, 07 Mar 2006 01:04:00 GMT</pubDate><guid>http://www.aygfsteel.com/junhong/archive/2006/03/07/33960.html</guid><wfw:comment>http://www.aygfsteel.com/junhong/comments/33960.html</wfw:comment><comments>http://www.aygfsteel.com/junhong/archive/2006/03/07/33960.html#Feedback</comments><slash:comments>31</slash:comments><wfw:commentRss>http://www.aygfsteel.com/junhong/comments/commentRss/33960.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/junhong/services/trackbacks/33960.html</trackback:ping><description><![CDATA[<img height="20" src="http://www.aygfsteel.com/Emoticons/QQ/15.gif" width="20" border="0" />本h写的分页的标{,?net中的datagrid标签怼Q只需要设|几个属性就可以实现分页功能了,单方便,q且效率很高?br />我写的有两种分页的标{,一U是全部select 出来Q然后再分页的,q个pȝ在第一ơ访问的时候可能有Ҏ,但是在随后的讉K可是很快的,因ؓ数据已经都缓存以来的Qƈ且是在pageContext中的Q所以不会占用很多的资源。第二种是部分select 出来的,效率很高。如果有需要的朋友Q请留下Email地址?br />惌源代码的朋友请和我联pR?br />大家可以把用的情늻我说一下,以便我做整?br /><font color="#ff0000"><br /><b>本程序作了升U,请大家下载下边的q个q接q行下蝲Q以便用最新的版本?br />q次升修复了几个bugs.</b></font><br /><font color="#ff0000"><b><a href="/Files/junhong/splitpage.rar">请下载Splitpage.rar</a></b></font><br /><img style="WIDTH: 404px; HEIGHT: 611px" height="611" alt="testsplitpage.JPG" src="http://www.aygfsteel.com/images/blogjava_net/junhong/testsplitpage.JPG" width="399" border="0" /><br /><img src ="http://www.aygfsteel.com/junhong/aggbug/33960.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/junhong/" target="_blank">junhong</a> 2006-03-07 09:04 <a href="http://www.aygfsteel.com/junhong/archive/2006/03/07/33960.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">΢ɽ</a>| <a href="http://" target="_blank">˫</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ʩ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ܿ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">¹</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ϸ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ɰ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">˳</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ƽȪ</a>| <a href="http://" target="_blank">ʷ</a>| <a href="http://" target="_blank">ͨ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ԭ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank"></a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>