随笔 - 40, 文章 - 0, 评论 - 20, 引用 - 0
数据加载中……

2005年6月1日

J2me开发


一些资料:




http://www.csdn.net/subject/j2meTools/


http://news.csdn.net/news/newstopic/24/24127.shtml



posted @ 2006-11-01 15:30 月亮 阅读(205) | 评论 (0)编辑 收藏

游戏

有个输家,就一定有个赢家。我是输家,但我四周望了一圈,却没看到半个赢家,我想,赢家应该也是我了,你说呢?

posted @ 2006-09-12 15:35 月亮 阅读(203) | 评论 (1)编辑 收藏

vi命令详解

vi命令是unix下常用而重要命令,可在全屏幕方式下编辑一个或多个文件。若在vi执行时 
没有指定一个文件,那么vi命令会自动产生一个无名的空的工作文件。若指定的文件不存在, 
那么就按指定的文件名创建一个新的文件。若对文件的修改不保存的话,v i命令并不改变原 
来文件的内容。 

  注意:vi命令并不锁住所编辑的文件,因此多个用户可能在同时编辑一个文件,那么最后 
保存的文件版本将被保留。 

下面是vi命令使用的一些选项及含义:          

  -c sub-command 在对指定的文件编辑前,先执行指定的命令 sub-command . 

  -r filename 恢复指定的文件filename .          

  -R 将指定的文件以只读的方式放入编辑器中,这样不会保存对文件的任何修 改。 

  -y number 将编辑窗口的大小设为number行。          

  下面是vi编辑所处的三种模式:          

  .命令模式 进入vi时所处的模式。在此模式下用户可输入各种子命令对进行*作,如删除行、 
粘贴行、移向下一个字、移向不同行等。 

  .文本输入模式 在此模式下可以修改一行的内容并增添新行。在命令模式下键入a 、i 或 
c键可进入文本输入模式,按Escape键可返回命令模式。 

  .命令项模式 在此模式下,可以通过子命令输入更多的参数。如:w子命令要求输入一文 
件名,"/"子命令要求输入一个查找项。用户使用Escape键返回命令模式。 


下面是自命令模式下执行的,在同一行上移动的自命令:          

  h 将光标左移一格。          

  l 将光标右移一格。          

  j 将光标下移一格。          

  k 将光标上移一格。          

  w 将光标移到下一个小字的前面。          

  W 将光标移到下一个大字的前面。          

  b 将光标移到前一个小字的前面。          

  B 将光标移到前一个大字的前面。          

  e 将光标移到下一个小字的后面。          

  E 将光标移到前一个大字的后面。          

  fc 把光标移到同一行的下一个c字符处。          

  Fc 把光标移到同一行的前一个c字符处。          

  tc 把光标移到同一行的下一个字符c的前一格。          

  Tc 把光标移到同一行的前一个字符c的后一格。          

  number| 把光标移到递number列上。          

下面是命令模式下在行间移动的子命令:          

  +或Enter 把光标移至下一行第一个非空白字符。          

  - 把光标移至上一行第一个非空白字符。          

  0 把光标移到当前行的第一个字符处。          

  $ 把光标移到当前行的最后一个字符处。          

  H 把光标移到屏幕最顶端一行。          

  L 把光标移到屏幕最底端一行。          

  M 把光标移到屏幕中间。          

下面是命令模式下改变屏幕显示的子命令:          

  z- 把当前行作为屏幕的最后一行,并重新显示屏幕。          

  z. 把当前行作为屏幕的中间一行,并重新显示屏幕。          

  Ctrl+l 重新显示屏幕当前内容。          

  /pattern/z- 寻找pattern的下一个位置,并把所在行设为屏幕的最后一行。 

下面是在命令模式下用来显示页面的子命令:          

  Ctrl + f向后滚一页。          

  Ctrl + d向后滚半页。          

  Ctrl + b向前滚一页。          

  Ctrl + u向前滚半页。          

  Ctrl + e屏幕向下滚一行。          

  Ctrl + y屏幕项上滚一行。          

下面是在命令模式下用来查找字符串所使用的子命令:          

  /pattern 向后寻找指定的pattern ,若遇到文件尾,则从头再开始。 

  ?pattern 向前寻找指定的pattern ,若遇到文件头,则从尾再开始。 

  n 在上次指定的方向上,再次执行上次定义的查找。          

  N 在上次指定的方向的相反方向上,再次执行上次定义的查找。          

  /pattern/+number 将光标停在包含pattern的行后面第number行上。 

  /pattern/-number 将光标停在包含pattern的行前面第number行上。 

  % 移到匹配的"()"或"{}"上。          

下面是在文本输入模式下用来输入文本的子命令(用户可在任何时候按Escape返回到命令模式): 

  a 在光标之后开始输入文本。          

  A在行尾开始输入文本。          

  i在光标之前开始输入文本。          

  I在行首第一个非空白字符前输入文本。          

  o在光标所在行后插入一空行。          

  O在光标所在行前插入一空行。          

下面是在命令模式下改变文本所使用的子命令(用户可在任何的时候按Escape键返回到命令模式): 

  cc或S 修改一整行。          

  C 改变一行光标位置以后的部分。          

  cw 改变光标所在单词。          

  dd删除当前行。          

  D 删除光标所在行光标后面的内容。          

  dw删除光标所在的单词。          

  J 把下一行内容加到本行行尾。          

  rc把光符所在字符替换成c .          

  R 覆盖本行内容。          

  u恢复上一次的修改。          

  x删除光标所在的字符。          

  ~ 改变光标所在出字符的大小写。          

  . 重复上一个*作。          

  <<把当前行移到左边。          

  >>把当前行移到右边。          

下面是用于文件中拷贝文本的字命令:          

  p 将缓冲区内容取到光标所在行的下面一行。          

  P 将缓冲区内容取到光标所在行的上面一行。          

  "bd 将文本删除至有名缓冲区b .          

  "bp 张贴有名缓冲区b中内容。          

  yy把当前行放入缓冲区。          

  Y 把当前行放入缓冲区。          

  Yw把光标所在的单词放入缓冲区。          

下面是用于保存文件的子命令:          

  :w 回写修改后的文件。          

  :w filename 当filename不存在时,把修改后的文件存为文件filename ,当文件filename 
存在时,报错。 

  !w filename 如果文件filename存在时,把修改后的文件保存为文件filename . 

下面列出了在vi编辑的多个文件之间切换所用的子命令:          

  :n开始编辑vi激活的文件列表中的下一个文件。          

  :n filenames 指定将被编辑的新的文件列表。          

下面列出了用于在当前文件和另外一个文件间切换的子命令:          

  :e filename 使用filename激活vi (在vi中装入另一个文件filename)。 

  e!重新装入当前文件,若当前文件有改动,则丢弃以前的改动。          

  :e+filename 使用filename激活vi ,并从文件尾部开始编辑。 

  :e+number filename 使用filename激活vi ,并在第number行开始编辑。 

  :e# 开始编辑另外一个文件。          

下面是在本文件中加入其他文件代码所使用的子命令:          

  :r filename读取filename文件,并将其内容加到当前文件后。   

  :r ! command执行command文件,并将其输出加到当前文件后。   

下面是vi中其他的子命令:          

  ctrl+g 取得正在编辑文件的有关信息。          

  :sh启动sh ,从sh中返回可用exit或ctrl+d .          

  :! Command 执行命令command .          

  !!重新执行上次的:! Command子命令。          

  :q退出vi ,若用户对编辑的文件有所修改,系统不会让用户使用q命令退出。   

  :q!退出vi而不管是否对文件有改动。          

  ZZ或:wq 保存对文件的修改并退出vi .          

  用户可在一个特殊的文件.exrc中定义特殊的vi命令。在vi中使用这些命令时,必须在该 
命令前加上一个冒号( :) 。

posted @ 2006-05-13 15:13 月亮 阅读(334) | 评论 (0)编辑 收藏

精通Log4j

 log4j虽然总的来说是比较容易使用的,但是要是想比较精通的操纵它还是有很多地方值得探讨的。
    这几天有空,把项目中大家用到的log4j实现的功能分了一下类,大致分为下面三类:
    <1>所有的日志信息都输出到log.log.
    <2>对于一些特殊的日志(如启动时候的日志),输出到log/startup/startup.log.
    <3>对于某些特殊包下面的日志,如com.aspire包下面的error信息都输出到error.log   
    有了这几个功能,相信对于大部分的系统都是够用的了,下面这个例子就是实现了这几个功能:
    (至于其他的一些配置,如格式这些的就不说明,有很多这种资料)
   
    ***********  log4j 配置文件  ************   
   
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" threshold="debug">

<appender name="file" class="org.apache.log4j.RollingFileAppender">
 <param name="File" value="log.log"/>
 <layout class="org.apache.log4j.PatternLayout">
 <param name="ConversionPattern" value=" %d{ISO8601} [%c]- %m%n"/>
 </layout>
</appender>

<appender name="error" class="org.apache.log4j.RollingFileAppender">
  <param name="File" value="error.log"/>
  <param name="MaxBackupIndex" value="300"/>
  <param name="Encoding" value="GB2312"/>
  <param name="MaxFileSize" value="20MB"/>
  <layout class="org.apache.log4j.PatternLayout">
   <param name="ConversionPattern" value="%d{ISO8601} %p [%c] - [%m]%n"/>
  </layout>
    <filter class="org.apache.log4j.varia.LevelRangeFilter">
  <!-- 过滤,只记录error信息-->
  <param name="LevelMin" value="error"/>
  <param name="LevelMax" value="error"/>
  <param name="acceptOnMatch" value="true"/>
    </filter>
</appender>
<appender name="startup" class="com.aspire.TimeSizeRollingFileAppender">
  <!--该类使自己从FileAppender派生,可以自己控制输出文件的路径 -->
  <param name="File" value="log/startup/startup.log" />
  <param name="Encoding" value="GBK" />
  <layout class="org.apache.log4j.PatternLayout">
   <param name="ConversionPattern" value="%m %d{ISO8601}- %m%n %p %l%n" />
  </layout>
</appender>

<logger name="biz.startup">
<!--Logger logger = Logger.getLogger("biz.startup") 可以这样来调用本logger-->
  <level value="debug" />
  <appender-ref ref="startup" />
</logger>

<logger name="com.aspire" additivity="false">
<!--Log log = LogFactory.getLog(TestLog4j.class) 此时如果TestLog4j
    位于com.aspire包下面,那么使用本logger
 -->
  <level value="debug"/>
  <appender-ref ref="error"/>
</logger>
<root>
<level value="info"/>
<!-- 默认输出到log.log-->
<appender-ref ref="file"/>
</root>
</log4j:configuration>

***********  log4j 配置文件结束 ************

**********  派生的TimeSizeRollingFileAppender类*****
package com.aspire;

import org.apache.log4j.FileAppender;
import org.apache.log4j.spi.ErrorCode;
import java.io.File;
import java.io.IOException;

public class TimeSizeRollingFileAppender
    extends FileAppender
    implements ErrorCode {

  private final static String FS = System.getProperty("file.separator");
  public TimeSizeRollingFileAppender() {
  }
  public void setFile(String file) {
    String val = file.trim();
    File domain = new File(".");
    try {
      fileName = domain.getCanonicalPath() + FS + val;
    }
    catch (IOException ex) {
      ex.printStackTrace();
    }
  }
}

********** TimeSizeRollingFileAppender 类结束 ******

************ 调用示例 TestLog4j类 **************
package com.aspire;

import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.xml.DOMConfigurator;
import org.apache.commons.logging.Log;

public class TestLog4j {
  private Logger logger = Logger.getLogger("biz.startup");
  private Log log = LogFactory.getLog(TestLog4j.class);

  public static void config(){
    DOMConfigurator.configure("conf\\log4jConf.xml");
  }
  public void Test(){
    /**
     * error > warn > info > debug
     */
    logger.error("*****error*****");
    logger.debug("****debug*****");
    logger.warn("*****warn******");
    logger.info("*****info******");
    log.error("中华之崛起!");
  }
  public static void main(String [] argv){
    TestLog4j t = new TestLog4j();
    TestLog4j.config();
    t.Test();
  }
}

***************  TestLog4j end ***********

posted @ 2006-04-26 12:59 月亮 阅读(390) | 评论 (0)编辑 收藏

23种经典的设计模式_Prototype模式(原形模式)

很多时候,创建对象的时候,只是在某些属性值上有区别,而大部分都很相似,但是这样的对象的初始化相对来说比较复杂,而且
需要耗费较长的时间或资源,这种情况下,我们可以考虑使用Prototype模式。我觉得这种模式实用于这样的情况:如果该类的用户对于该
类的对象是怎么创建的,对类的内部结构这些都不关心的情况,并且该类的创建过程比较费时或资源时,可以考虑使用该模式。下面是该模式的
一个例子:

Prototype 类

package com.moonsoft;

import java.lang.Cloneable;
public class Prototype implements Cloneable {
 
 public String myname;
 
 Prototype(){
  System.out.println("start:"+System.currentTimeMillis());
  for( int i=0; i< 9999999; i++){   
  }
  System.out.println("end:"+System.currentTimeMillis());
 }
 
 public Object clone(){
  Object o = null;
  try{
   o = super.clone();   
  }
  catch(CloneNotSupportedException ex){
   ex.printStackTrace();
  }
  return o;
 }
 
 public void whoami(){
  System.out.println(myname);
 }
}


测试类

package com.moonsoft;

public class Test {
 
 public static void main(String [] argv){
  Prototype  p = new Prototype();
  p.whoami();
  p.myname = "loucy";
  Prototype  p1 = (Prototype)p.clone();
  p1.whoami(); 
  
 }
}

posted @ 2006-04-16 15:21 月亮 阅读(548) | 评论 (0)编辑 收藏

小技巧_jsp缓存问题的解决

如果一直为jsp的缓存问题困扰的话,可以试试在jsp中加入以下几句话:

<head>
<meta http-equiv="Cache-Control" content="max-age=0" forua="true" />
<meta http-equiv="Cache-Control" content="no-cache" forua="true"/>
<meta http-equiv="Cache-Control" content="must-revalidate" forua="true" />
</head>

max-age=30 就表示缓存的最长存在时间是30s,no-cache表示无缓存,must-revalidate表示每次访问必须重新验证是否有更新!

posted @ 2006-04-04 15:11 月亮 阅读(657) | 评论 (0)编辑 收藏

用Java实现的Html web服务器

  马上就要开始转到新的项目组,做一个全新的项目了,对于HTTP协议需要一定的了解,所以周末自己用Java写了一个简单的web服务器试试,只能实现简单的html文件浏览。

主要包括三个类:WebServer(监听浏览器请求),SocketThread(处理浏览器请求的进程),StringUtil(实现一些公共的操作),下面是三个类的代码.


----WebServer----
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class WebServer {
 
 public static void main(String[] argv) throws IOException {
  ServerSocket servSocket = new ServerSocket(StringUtil.LISTENING_PORT);
  try {
   while (true) {
    Socket socket = servSocket.accept();
    new SocketThread(socket).start();
   }
  } finally {
   servSocket.close();
  }
 }
}

---SocketThread------
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.Writer;
import java.net.Socket;

public class SocketThread extends Thread {
 private Socket socket = null;

 public SocketThread(Socket s) {
  this.socket = s;
 }

 public void run() {
  try {
   if (socket == null) {
    throw new Exception("==>SOCKET为空<==");
   }
   BufferedReader reader = new BufferedReader(new InputStreamReader(
     socket.getInputStream()));
   String fileName = "";
   while (true) {
    String str = reader.readLine();
    if (str == null || str.length() <= 0) {
     break;
    }
    //System.out.println("===>"+str);
    if (StringUtil.isGetRequestInfo(str)) {
     fileName = StringUtil.getFileName(str);
     break;
    }
   }
   //System.out.println("===>客户机IP==>"+socket.getInetAddress().toString());
   //System.out.println("===>客户机端口==>"+socket.getPort());   
   /*
    BufferedWriter writer = new BufferedWriter(new
    OutputStreamWriter(socket.getOutputStream()));
    */
   PrintStream outputStream = new PrintStream(socket.getOutputStream());
   File file = new File(StringUtil.WEBPATH + fileName);
   if (file.exists()) { //如果文件存在
    StringUtil.sendHttpHead(outputStream, file);
    StringUtil.sendFile(outputStream, file);
    outputStream.flush();
   } else { //文件没找到,返回404页面
    StringUtil.send404Page(outputStream);
    outputStream.flush();
   }
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   try {
    socket.close();
   } catch (Exception e) {
   }
  }
 }

}



---StringUtil-----
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.PrintStream;

/**
 * @author xiaoliang
 */
public class StringUtil {

 // 服务器监听的端口
 public static final int LISTENING_PORT = 8080;

 // 服务器文件的位置
 public static final String WEBPATH = "E:";

 /**
  * 判断该字符串是不是浏览器发送过来的请求头信息
  * @param str
  * @return
  */
 public static boolean isGetRequestInfo(String str) {
  if (str == null || str.length() <= 0)
   return false;
  boolean isGetStr = true;
  if (str.indexOf("GET") != 0) {
   isGetStr = false;
  }
  if (str.indexOf("HTTP/") <= 0) {
   isGetStr = false;
  }
  return isGetStr;
 }

 /**
  * 获得请求信息中的文件名,默认为index.html
  *
  * @param str
  * @return
  */
 public static String getFileName(String str) {
  String fileName = "index.html", s;
  int httpIndex = str.lastIndexOf("HTTP/");
  s = str.substring(3, httpIndex);
  s = s.trim();
  if (s != null && s.length() > 0 && s.indexOf(".") > 0) {
   fileName = s;
  }
  return fileName;
 }

 /**
  * 发送文件到客户端
  *
  * @param out
  * @param file
  */
 public static void sendFile(PrintStream out, File file) {
  try {
   DataInputStream in = new DataInputStream(new FileInputStream(file));
   int length = (int) file.length();
   byte[] buffer = new byte[length];
   in.readFully(buffer);
   out.write(buffer, 0, length);
   in.close();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 /**
  * 发送返回的头部信息
  * @param out
  */
 public static void sendHttpHead(PrintStream outputStream, File file) {
  try {
   outputStream.println("HTTP/1.0200OK");
   outputStream.println("Content_Type:text/htm1");
   outputStream.println("Content_Length:" + file.length());
   outputStream.println("Server:moon webserver 1.0");
   outputStream.println("");
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 /**
  * 返回404页面
  * @param out
  */
 public static void send404Page(PrintStream out) {
  try {
   out.println("HTTP /1.0 404 no found");
   out.println("Content_type:text/html");
   out.println("");
   out.println("Error404:file not found!");
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 
 public static void main(String[] argv) {
  String str = "GET /11.html HTTP/1.1";
  str = StringUtil.getFileName(str);
  System.out.println("==>" + str + "<==");
  File file = new File(StringUtil.WEBPATH + str);
  if (file.exists()) {
   System.out.println("exists");
  } else {
   System.out.println("not exists");
  }
 }

}

posted @ 2006-03-28 13:55 月亮 阅读(448) | 评论 (0)编辑 收藏

Apache FileUpload 使用

FileUpload 组件使用注意:
1>
首先创建一个HTML页面。注意,凡是要上载文件的表单都必须设置enctype属性,且属性的值必须是multipart/form-data,同时请求方法必须是POST.
<form name="myform" action="fileuploaddemo.jsp"  method="post" enctype="multipart/form-data">
 
2>commons-fileupload-1.1.jar和commons-io-1.1.jar 两个包都要引入,
因为在parseRequest(request)的类有关继承于DiskFileItem类。

3>示例
      //检查表单是否正确
      boolean isMultipart = FileUpload.isMultipartContent(request);
      DiskFileItemFactory  factory = new DiskFileItemFactory();
      ServletFileUpload upload = new ServletFileUpload(factory);
      //文件最大,设为-1表示不受限制
      upload.setSizeMax(4096);
      //解析请求,把解析的结果放在一个List里面
      List items = upload.parseRequest(request);
      //缓存大小,设为-1表示不受限制
      factory.setSizeThreshold(4096);
      //设置临时目录
      factory.setRepository(new File("D:\\temp"));
      Iterator iter = items.iterator();
      while( iter.hasNext() ){
        FileItem item  = (FileItem)iter.next();
        //检查是一个普通的表单域还是File组件
        if( !item.isFormField() ){
          System.out.println("FileName:==>"+item.getName());
          System.out.println("FieldName:==>"+item.getFieldName());
          System.out.println("Size:==>"+item.getSize());
          //item.getName 返回的是完整的文件名,如:E:\\xx\11.doc
          //所以这里用一个fullFile来取文件名
          File fullFile  = new File(item.getName());
          File uploadedFile = new File("D:\\ftp\\",fullFile.getName());
          item.write(uploadedFile);
        }
      }

posted @ 2006-03-06 12:33 月亮 阅读(1841) | 评论 (1)编辑 收藏

EJB QL

从一个表users中查询记录,如果是写成
select  i from  users as  i  where i.name=?1则编译EJB的时候会报错,但是如果把users 首字母大写就OK了。
select  i from  Users as  i  where i.name=?1

posted @ 2006-02-27 23:34 月亮 阅读(237) | 评论 (0)编辑 收藏

EJb 会话Bean

在EJB容器中,SessionBean主要有两种:无状态(stateless)和有状态(stateful)。
1、无状态EJB,类似Servlet,它只提供一个引用(Bean instance),被所有客户端使用,不保留某个客户的单独信息。
例如:在某无状态EJB中,有一个数据成员(变量) i_count (整型,用于访问计数,初始值为0,访问一次累加1),它是公共的。某客户端访问后,值累加为1。另一个客户端访问时是已经变化了的值为1。

2、有状态EJB,类似数据库的Connect链接,也类似线程守护,它提供引用池(Bean instance pool),每个客户端会有单独的信息。
例如:在某有状态EJB中,有一个数据成员(变量) i_count (整型,用于访问计数,初始值为0,访问一次累加1),它对每个客户端来说是隔离的。某客户端访问后,值累加为1。另一个客户端访问时还是原来的值为0。

这里提到的数据成员(变量) i_count ,在EJB规范中称作:conversational state 。对它的要求也很多的,例如类型为 Serializable objects。还有,还要在ejbActivate(),ejbPassivate(),ejbRemove()等生命周期约定的方法中处理。详见EJB规范吧。

我的感想:在看第一遍书时,还一点感觉都没有,根本就看不明白SessionBean中的session与Servlet容器中的session有什么区别。
动手编程后,才感觉到EJB只是比Servlet更规范,更重量而已。真正的区别就是接口协议一个是基于HTTP,一个是基于RMI/IIOP。Servlet与无状态的SessionBean在Session上是一样的控制。Servlet中的Session对象与有状态的SessionBean是一样的控制。
对于应用,例如有一个购物车,要记录正在采购的物品信息,没有EJB时,我们一般是存在Servlet容器中的session中。有了EJB,则可以存储在有状态的SessionBean中,并且该次有状态的sessionBean的instance还得保存在Servlet的session中。这样的好处是:至少可以减轻Servlet容器的负载。



转自:
http://zengabo.blogchina.com/blog/527365.html

posted @ 2006-02-22 16:35 月亮 阅读(247) | 评论 (0)编辑 收藏

Ibatis示例


1.将ibatis 的jar 包添加到工程中

2.先新建一个xml文件 SqlMap.xml,在这个文件中定义使用了哪些ibatis资源文件
<?xml version="1.0" encoding="gb2312"?>
<!DOCTYPE sql-map-config PUBLIC "-//iBATIS.com//DTD SQL Map Config 1.0//EN"
    "http://www.ibatis.com/dtd/sql-map-config.dtd">
<sql-map-config>
  <sql-map  resource="com/montersoft/ibatis/common/monter.xml"/>
</sql-map-config>

3.定义资源文件monter.xml
<?xml version="1.0" encoding="gb2312"?>
<!DOCTYPE sql-map
    PUBLIC "-//iBATIS.com//DTD SQL Map 1.0//EN"
    "http://www.ibatis.com/dtd/sql-map.dtd">
<sql-map name="monter">
   <result-map name="monterInfo" class="java.util.HashMap">
     <property name="id"  column="id" type="VARCHAR"/>
     <property name="name" column="name" type="VARCHAR"/>
     <property name="age"  column="age"  type="NUMBERIC"/>
   </result-map>  
   <dynamic-mapped-statement name="monter_getByPk" result-map="monterInfo">
   select id,name,age from monter where id = #id#
   </dynamic-mapped-statement>
</sql-map>

**注意dynamic-mapped-statement的name 必须唯一

4.定义一个公共类来生成SqlMap
package com.montersoft.ibatis.common;
import java.io.Reader;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.ibatis.common.resources.Resources;
import com.ibatis.db.sqlmap.SqlMap;
import com.ibatis.db.sqlmap.XmlSqlMapBuilder;
public class SqlMapUtil { 
 private static Log loger = LogFactory.getLog(SqlMapUtil.class);
 public  static SqlMap  sqlMap ; 
 public static SqlMap loadSqlMap(){
  Reader reader = null;
  try{
   reader = Resources.getResourceAsReader("com/montersoft/ibatis/common/SqlMap.xml");
   return XmlSqlMapBuilder.buildSqlMap(reader);
  }
  catch(Exception e){   
   loger.error("there is a error=>"+e.getMessage());
  }
  return null;
 } 
 public static SqlMap getSqlMap(){
  if( sqlMap == null )
   sqlMap = loadSqlMap();
  return sqlMap;
 } 
}
5.再新建DAO,Vo,
public interface  IVO { 
}
public class MonterVo implements IVO{ 
 public String id ;
 public String name;
 public int age;
 ...省去 get ,set 方法
}
public class MonterDao { 
   public IVO getBkPK(Connection conn,IVO vo) throws Exception{
    try{    
    Object map  =  SqlMapUtil.getSqlMap().
       getMappedStatement("monter_getByPk").executeQueryForObject(conn,vo);
    return   copyMap2Vo(map);
    }
    catch(Exception e){       
        throw new Exception(e.getMessage());
    }
   }  
   private IVO copyMap2Vo(Object map){
    MonterVo vo = new MonterVo();
  try{
   BeanUtils.copyProperties(vo,map);
  }
  catch(Exception e){
   e.printStackTrace();
  }
  return vo;
 }
}

6.至此就建立了一个简单的ibatis示例.

posted @ 2006-01-06 16:39 月亮 阅读(329) | 评论 (0)编辑 收藏

通过weblogic的数据源获得数据库连接的方法

通过weblogic的数据源获得数据库连接的方法:

package com.moonsoft.datasource;

import javax.naming.NamingException;
import java.util.Hashtable;
import javax.naming.InitialContext;
import java.sql.Connection;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class TestDataSource {

  public static String WEB_URL = "t3://localhost:9000";
  public static String DATA_SOURCE = "JDBCDS";
  public static String weblogic_context_factory =
      "weblogic.jndi.WLInitialContextFactory";
  public TestDataSource() {
  }
  public static Object lookUp() throws NamingException {
    Hashtable env = new Hashtable();
    env.put(InitialContext.INITIAL_CONTEXT_FACTORY, weblogic_context_factory);
    env.put(InitialContext.PROVIDER_URL, WEB_URL);
    InitialContext tempContext = new InitialContext(env);
    return tempContext.lookup(DATA_SOURCE);
  }
  public static Connection getConnection() throws SQLException {
    Connection conn = null;
    try {
      DataSource ds = (DataSource) lookUp();
      if (ds == null) {
        throw new SQLException("查询到空数据源!");
      }
      conn = ds.getConnection();
    }
    catch (NamingException ex) {
      ex.printStackTrace();
    }
    return conn;
  }
  public static void releaseConnection(Connection conn, PreparedStatement sta,
                                       ResultSet rs) {
    try {
      if (rs != null) {
        rs.close();
      }
      if (sta != null)
        sta.close();
      if (conn != null)
        conn.close();
    }
    catch (Exception ex) {
      ex.printStackTrace();
    }
  }
  public static void testSearch() {
    Connection conn = null;
    PreparedStatement sta = null;
    ResultSet rs = null;
    try {
      conn = getConnection();
      String sql = "select * from admin_config where config_name like ?";
      sta = conn.prepareStatement(sql);
      sta.setString(1,"%Sms%");
      rs = sta.executeQuery();
      if (rs != null) {
        while (rs.next()) {
          System.out.println(rs.getString(1));
        }
      }
    }
    catch (Exception ex) {
      ex.printStackTrace();
    }
    finally {
      releaseConnection(conn,sta,rs);
    }
  }
  public static void main(String [] argv){
    testSearch();
  }
}

posted @ 2006-01-05 10:51 月亮 阅读(1239) | 评论 (0)编辑 收藏

一个设计中使用比较多的模式

如果是在需求还没确定或者是在两个类实现相近功能时候,会大量使用下面的方式:
--抽象类,注意其中的newInstance方法的实现
package com.moonsoft.design;
public  abstract class Moon {
  public static Moon newInstance(String classStr){
    Class re;
    try {
      re =  Class.forName(classStr);
      return (Moon)re.newInstance();
    }
    catch (Exception ex) {
      ex.printStackTrace();
    }
    return null;
  }
  public abstract void  println();
}
--从Moon类派生出来的一个字类,提供println方法的一种实现方式
package com.moonsoft.design;
public class Moon1 extends Moon {
  public void println(){
    System.out.println("I am moon1");
  }
  public void myprintln(){
    System.out.println("I am moon1 myprintln");
  }
}
--从Moon类派生出来的另一个字类,提供println方法的另一种实现方式
package com.moonsoft.design;
public class Moon2 extends Moon {
   public void println(){
    System.out.println("I am moon2!");
  }
}
--调用
 Moon moon = Moon.newInstance("com.moonsoft.design.Moon1");
 moon.println();
 或
 Moon moon = Moon.newInstance("com.moonsoft.design.Moon2");
 moon.println();

posted @ 2006-01-04 16:41 月亮 阅读(100) | 评论 (0)编辑 收藏

JSP标签的使用方法


如要在JSP页面上有一个链接,Url值是通过参数输入的,用JSP标签的实现步骤(当然实际中不会用标签来完成这么简单的功能):

<一>.先从javax.servlet.jsp.tagext.BodyTagSupport派生一个新的类,并重载它的doStartTag()方法.如果是想要传入参数的话,则还要在Bean中加入想要的变量,如这里要传入一个url值,所以添加一个参数:linkUrl. 最后代码如下:

package com.moonsoft.jsptag;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.JspException;
public class UrlLinkTag extends BodyTagSupport  {
  private String linkUrl;
  public UrlLinkTag() {
  }
  public String getLinkUrl() {
    return linkUrl;
  }
  public void setLinkUrl(String linkUrl) {
    this.linkUrl = linkUrl;
  }
  public int doStartTag() throws JspException{
    try {
      this.pageContext
          .getOut().print("<a href=\'"+linkUrl+"\' >"+linkUrl+"</a>");
    }
    catch (Exception ex) {
      ex.printStackTrace();
    }
    return 0;
  }
}

<二>新建一个tld文件,内容如下:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
 "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
 <taglib>
        <tlibversion>1.0</tlibversion>
 <jspversion>1.1</jspversion>
 <shortname>buttons</shortname>
 <uri>http://www.borland.com/jbuilder/internetbeans.tld</uri>
 <info>
 JSP tag extensions for InternetBeans Express
  </info>
    <tag>
 <name>urllink</name>
 <tagclass>com.moonsoft.jsptag.UrlLinkTag</tagclass>
 <bodycontent>jsp</bodycontent>
 <attribute>
  <name>linkUrl</name>
  <required>true</required>
  <rtexprvalue>true</rtexprvalue>
 </attribute>
    </tag>
   </taglib>
  
<三>在web.xml中引入这个taglib,在其中加入:

<taglib>
    <taglib-uri>/moon</taglib-uri>
    <taglib-location>/WEB-INF/classes/com/moonsoft/jsptag/UrlLinkTag.tld</taglib-location>
</taglib>


<四>在jsp中引入这个标签
<%@ taglib uri="/moon" prefix="mylinkurl" %>
这里uri是和web.xml中配置的taglib-uri对应的,prefix值只是在本jsp页面作为标示用.

下面就可以在jsp中使用这个标签了:

<mylinkurl:urllink linkUrl="http://www.baidu.com" />

这里面的mylinkurl为在本jsp页面中设置的prefix值,urllink为tld文件中tag name,linkUrl为输入的参数

这样就在jsp页面上加入了一个:
<a href='http://www.baidu.com' >http://www.baidu.com</a>链接

posted @ 2005-12-29 13:47 月亮 阅读(1425) | 评论 (0)编辑 收藏

Java Excel 使用攻略

 现在正在做的项目中涉及大量的Excel文件导出导入操作,都是使用Java Excel来操作。

Java Excel是一开放源码项目,通过它Java开发人员可以读取Excel文件的内容、创建新的Excel文件、更新已经存在的Excel文件。下面我写了一个简单的例子,展示基本的读取,新建,更新(包括常见格式的设置:字体,颜色,背景,合并单元格),拷贝操作,有这些其实已经基本足够应付大部分问题了。下面是例的源代码:

import java.io.*;
import java.util.Date;

import jxl.*;
import jxl.format.Colour;
import jxl.format.UnderlineStyle;
import jxl.read.biff.BiffException;
import jxl.write.*;
import jxl.format.UnderlineStyle;
import jxl.format.CellFormat;;

public class OperateExcel {
 
 /**
  * Read data from a excel file
  */
 public static void  readExcel(String excelFileName){
  Workbook  rwb = null;  
  try{
   InputStream stream = new FileInputStream(excelFileName);
   rwb = Workbook.getWorkbook(stream);
   Sheet  sheet = rwb.getSheet(0);
   Cell   cell  = null;
   int columns = sheet.getColumns();
   int rows    = sheet.getRows();
   for( int i=0 ; i< rows ; i++ )
    for( int j=0 ; j< columns ; j++){
     //attention: The first parameter is column,the second parameter is row.  
     cell = sheet.getCell(j,i);    
     String str00 = cell.getContents();
     if( cell.getType() == CellType.LABEL )
       str00 += " LAEBL";
     else if( cell.getType() == CellType.NUMBER)
       str00 += " number";
     else if( cell.getType() == CellType.DATE)
       str00 += " date"; 
     System.out.println("00==>"+str00);
    } 
   stream.close();
  }
  catch(IOException e){  
   e.printStackTrace();
  }
  catch(BiffException e){
   e.printStackTrace();
  } 
  finally{  
   rwb.close();
  }
 }
 /**
  * create a new excelFile
  * @param excelFileName create name
  */
 public static void createExcelFile(String excelFileName){
  try{
   WritableWorkbook wwb = Workbook.createWorkbook(new File(excelFileName));
   WritableSheet     ws  = wwb.createSheet("sheet1",0);
   //also,The first parameter is  column,the second parameter is row.
   // add normal label data
   Label label00 = new Label(0,0,"Label00");
   ws.addCell(label00);
   //add font formating data   
   WritableFont  wf = new WritableFont(WritableFont.TIMES, 18, WritableFont.BOLD , true);
   WritableCellFormat wff = new WritableCellFormat(wf);
   Label label10 = new Label(1,0,"Label10",wff);
   ws.addCell(label10);
   //add color font formating data
   WritableFont wf_color = new WritableFont(WritableFont.ARIAL,10,WritableFont.NO_BOLD,false,UnderlineStyle.DOUBLE_ACCOUNTING,Colour.RED);
   WritableCellFormat wff_color = new WritableCellFormat(wf_color);
   wff_color.setBackground(Colour.GRAY_25); //set background coloe to gray  
   Label label20 = new Label(2,0,"Label20",wff_color);   
   ws.addCell(label20);
   
   //合并单元格
   WritableFont wf_merge = new WritableFont(WritableFont.ARIAL,10,WritableFont.NO_BOLD,false,UnderlineStyle.DOUBLE_ACCOUNTING,Colour.GREEN);
   WritableCellFormat wff_merge = new WritableCellFormat(wf_merge);
   wff_merge.setBackground(Colour.BLACK);
   Label label30 = new Label(3,0,"Label30",wff_merge);   
   ws.addCell(label30);
   Label label40 = new Label(4,0,"Label40");
   ws.addCell(label40);
   Label label50 = new Label(5,0,"Label50");
   ws.addCell(label50);
     //合并 (0,3) (4,0)
     //attention : 如果合并后面的列不为空,那么就把后面格的内容清空,格式也是按前一个单元格的格式
   ws.mergeCells(3,0,4,0);
   
   //添加Number格式数据
   jxl.write.Number labelN = new jxl.write.Number(0, 1, 3.1415926);
   ws.addCell(labelN);
   
   //添加带有formatting的Number对象
   jxl.write.NumberFormat nf = new jxl.write.NumberFormat("#.##");
   jxl.write.WritableCellFormat wcfN = new jxl.write.WritableCellFormat(nf);
   jxl.write.Number labelNF = new jxl.write.Number(1, 1, 3.1415926, wcfN);
   ws.addCell(labelNF);
   
   //添加Boolean对象
   jxl.write.Boolean labelBoolean = new jxl.write.Boolean(2,1,false);
   ws.addCell(labelBoolean);
   
   //添加DateTime对象
   DateTime labelDT = new DateTime(3,1,new Date());
   ws.addCell(labelDT);
   
   //添加带有格式的DataTime数据
   DateFormat dtf = new DateFormat("yyyy-MM-dd hh:mm:ss");
   WritableCellFormat wcfDt = new WritableCellFormat(dtf);   
   wcfDt.setBackground(Colour.YELLOW);
   DateTime labelDT_format =  new DateTime(4,1,new java.util.Date(),wcfDt);
   ws.addCell(labelDT_format);
   ws.mergeCells(4,1,5,1); //比较长,用两列来显示     
   
   wwb.write();
   wwb.close();
  }
  catch(IOException e){
   e.printStackTrace();
  }
  catch(WriteException e){
   e.printStackTrace();
  }  
 }
 /**
  * 如何更新Excel文件
  * @param fileName
  */
 public static void updateExcel(String fileName){  
  try{
   jxl.Workbook rw = jxl.Workbook.getWorkbook(new File(fileName));
   WritableWorkbook wwb = Workbook.createWorkbook(new File(fileName),rw);
   //这里其实执行的是一次copy操作,把文件先读到内存中,修改后再保存覆盖原来的文件来实现update操作
   WritableSheet ws  = wwb.getSheet(0);
   WritableCell wc = ws.getWritableCell(0,0);
   if( wc.getType() == CellType.LABEL){
    Label l = (Label)wc;
    l.setString(wc.getContents()+"_new");
   }
   wwb.write();
   wwb.close();
  }
  catch(IOException e){
   e.printStackTrace();
  }
  catch(WriteException e){
   e.printStackTrace();
  } 
  catch(BiffException e){
   e.printStackTrace();
  }
 }
 /**
  * 如何copy Excel文件
  * @param fileName
  */
 public static void copyExcel(String sourFileName,String destFileName){  
  try{
   jxl.Workbook rw = jxl.Workbook.getWorkbook(new File(sourFileName));
   WritableWorkbook wwb = Workbook.createWorkbook(new File(destFileName),rw);
   wwb.write();
   wwb.close();
  }
  catch(IOException e){
   e.printStackTrace();
  }
  catch(WriteException e){
   e.printStackTrace();
  } 
  catch(BiffException e){
   e.printStackTrace();
  }
 }
 
 public static void main(String [] argv){
  //OperateExcel.readExcel("E:\\test.xls");
  //OperateExcel.createExcelFile("E:\\test1.xls");
  //OperateExcel.updateExcel("E:\\test.xls");
  OperateExcel.copyExcel("E:\\test.xls","E:\\moon.xls");
 }

}


posted @ 2005-12-06 15:06 月亮 阅读(2197) | 评论 (4)编辑 收藏

执行过程中动态执行方法

在编程中可能回碰到一些到实际运行时才指定要调用的方法的需要,最典型的是Struct的DispatchAction类,
它能根据用户页面请求参数的不同来调用不同的方法来处理用户请求。我下面写了一个简单的例子来简单演示其
实现方法:

package learn;
import java.lang.NoSuchMethodException;
import java.lang.reflect.Method;
import java.util.Date;

public class TestMethod{
    protected Class clazz = this.getClass();
    protected Class[] no_parameter = {};  //方法无参数
    protected Class[] string_parameter = {String.class}; //以String 为参数
    protected Class[] int_parameter = {int.class};  //以int为参数
    protected Class[] multi_parameter = {String.class,Date.class}; //多个参数,第一个为String,第二二个为Date   
   
    public void method1(){
      System.out.println("method1");
    }
   
    public void method2(String str){
      System.out.println("method2=>"+str);
    }
   
    public void method3(int i){
      System.out.println("method2=>"+i);
    }
   
    public void method4(String str,Date date){
      System.out.println("method4=>"+str+"==="+date.toLocaleString());
    }
   
    public void execute(String methodName,int type,java.util.List list) throws Exception{
      try {
        Method  m = getMethod(methodName,type);
        int size = (list != null )? list.size():0;
        Object o [] = new Object[size];
        for( int i =0 ; i< size ; i++ )
          o[i] = list.get(i);  //准备参数
        m.invoke(this,o);
      }
      catch (Exception ex) {
        ex.printStackTrace();
        throw new Exception(ex.getMessage());
      }
    }
   
    private Method getMethod(String name,int type)throws NoSuchMethodException{
        Method m = null;
        switch(type){
          case 1:
            m = clazz.getMethod(name,no_parameter);
            break;
          case 2:
            m = clazz.getMethod(name,string_parameter);
            break;
          case 3:
            m = clazz.getMethod(name,int_parameter);
            break;
          case 4:
            m = clazz.getMethod(name,multi_parameter);
            break;
          default:
            m = clazz.getMethod(name,no_parameter);
        }
        return m;
    }
   
    public static void main(String [] argv){
      TestMethod testMethod = new TestMethod();
      try{
        java.util.List list = new java.util.ArrayList();
        testMethod.execute("method1", 1, list);
        list.add("
http://www.blogjava.net/minmoon");
        testMethod.execute("method2", 2, list);
        list.clear();
        list.add("
mailTo:xiaoliang@aspire-tech.com");
        list.add(new Date());
        testMethod.execute("method4",4,list);
      }
      catch(Exception e){
        e.printStackTrace();
      }
    }
}

其中几个关键的地方说明一下:
  clazz.getMethod(name,multi_parameter);  其中multi_parameter是要根据实际方法的参数来定义的。
  m.invoke(this,o);   o是要传入方法的参数列表。

posted @ 2005-11-23 00:18 月亮 阅读(484) | 评论 (0)编辑 收藏

23种面向对象的设计模式----Prototype模式


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

Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。

如何使用?
因为Java中的提供clone()方法来实现对象的克隆,所以Prototype模式实现一下子变得很简单.

以勺子为例:

public abstract class AbstractSpoon implements Cloneable
{
  String spoonName;

  public void setSpoonName(String spoonName) {this.spoonName = spoonName;}
  public String getSpoonName() {return this.spoonName;}

  public Object clone()
  {
    Object object = null;
    try {
      object = super.clone();
    } catch (CloneNotSupportedException exception) {
      System.err.println("AbstractSpoon is not Cloneable");
    }
    return object;
  }
}

有个具体实现(ConcretePrototype):

public class SoupSpoon extends AbstractSpoon
{
  public SoupSpoon()
  {
    setSpoonName("Soup Spoon");
  }
}

调用Prototype模式很简单:

AbstractSpoon spoon = new SoupSpoon();
AbstractSpoon spoon2 = spoon.clone();

当然也可以结合工厂模式来创建AbstractSpoon实例。

在Java中Prototype模式变成clone()方法的使用,由于Java的纯洁的面向对象特性,使得在Java中使用设计模式变得很自然,两者已经几乎是浑然一体了。这反映在很多模式上,如Interator遍历模式。



原文出处:http://www.jdon.com/designpatterns/prototype.htm

看看写的很好,就拿来引用一下,不用自己写的那么累^_^.

posted @ 2005-11-20 20:32 月亮 阅读(203) | 评论 (0)编辑 收藏

23种面向对象的设计模式----Factory method模式


Factory method,工厂方法模式,定义一个用于创建对象的接口,让字类决定实例化哪一个类。也就是使一个类的实例化延迟到其子类,提供一种方法使对象创建变得多态。
下面是我写的一个例子,如有两种工人,car worker和bus worker,所生成的产品分别是car 和 bus,我按照Factory method 的实现如下:


--先定义car 和 bus 的父类,都是一种产品
package Factory;
public class Product {
 
 public  void whoami(){
  System.out.println("I am a product!");
 }
}

--Car 类
package Factory;
public class Car extends Product { 
 public Car() {
 } 
 public void whoami(){
  System.out.println("I am a car!");
 } 
}
--Bus 类
package Factory;
public class Bus extends Product { 
 public Bus() {
 } 
 public void whoami(){
  System.out.println("I am a bus!");
 }
}
--定义CarWorker和BusWorker的父类 worker
package Factory;
public abstract class Worker { 
 private Product theProduct;
 public abstract Product  createProduct(); 
 public void work(){
  theProduct = createProduct();
 }
 public void showMessage(){
  this.theProduct.whoami();
 }
}
--Carworker
package Factory;
public class CarWorker extends Worker { 
 public Product createProduct(){
   return new Car();
 }
}
--BusWorker
package Factory;
public class BusWorker extends Worker { 
 public Product  createProduct(){
  return new Bus();
 }
}
--下面看看具体的调用
package Factory;
public class TestAll {

 public static void main(String [] argv){ 
  Worker  worker = new CarWorker();
  worker.work();
  worker.showMessage();
  
  Worker  worker1 = new BusWorker();
  worker1.work();
  worker1.showMessage(); 
 } 
}
可以看到虽然这样实现有一些麻烦,如新加一种产品时,就必须从Product类创建一个子类,但是这样做的
好处也是显而易见的,会给你系统带来更大的可扩展性和尽量少的修改量,再添加一种产品一种工人的时候,对以前的代码是不必做任何修改的。

<个人观点,仅作参考>

 

posted @ 2005-11-13 21:35 月亮 阅读(923) | 评论 (1)编辑 收藏

23种面向对象的设计模式----Singleton模式

  Singleton模式为单态模式或者叫孤子模式,保证一个类只有一个实例,并提供一个访问它的全局访问点。
  Singleton模式的使用范围比较广泛,对于一些类来说,只有一个实例是很重要的。比如,你要论坛中

的帖子计数器,每次浏览一次需要计数,单态类能否保持住这个计数,并且能synchronize的安全自动加

1,如果你要把这个数字永久保存到数据库,你可以在不修改单态接口的情况下方便的做到。
下面是一个简单的示例程序:
package Singleton;
public class TestSingleton { 
 private static TestSingleton  testSingleton = null;
 protected int  count = 0; 
 public static synchronized  TestSingleton getInstance(){
   if( testSingleton ==   null)
    testSingleton = new TestSingleton();
   return testSingleton;
 }
 public void addCount(){
  count ++;
 }
 public void showCount(){
  System.out.println("count :"+count);
 }  
}
我们还可以在这个基础上做一个扩展,如从上面例子中的TestSingleton类扩展出多个子类,在

getInstance方法中控制要使用的是哪个子类,具体实现代码如下:

-----TestSingleton.java
package Singleton;
public class TestSingleton { 
 private static TestSingleton  testSingleton = null;
 protected int  count = 0; 
 public static synchronized  TestSingleton getInstance(){
   if( testSingleton ==   null)
    testSingleton = new SubTestSingleton ();
   return testSingleton;
 }
 public void addCount(){
  count ++;
 }
 public void showCount(){
  System.out.println("TestSingleton count :"+count);
 }  
}

-----SubTestSingleton.java
public class SubTestSingleton extends TestSingleton{
 public void showCount(){
  System.out.println("SubTestSingleton count :"+count);
 }
}

<以上为个人见解,欢迎大家评论!>

posted @ 2005-11-13 15:54 月亮 阅读(662) | 评论 (0)编辑 收藏

面向对象的23种设计模式

  最近对面向对象的设计的23种经典的设计模式做了一个研究,接下来的Blog中我会按我的理解做个简单介绍并提供我写的示例代码,欢迎大家的评论,共同提高.
  
   

posted @ 2005-11-13 15:40 月亮 阅读(755) | 评论 (0)编辑 收藏

Oracle数据库查询一个月的记录的sql语句

Oracle数据库查询一个月的记录的sql语句:

select LASTUPDTIME from spprereg where
    (to_date('2005-5-1','YYYY-mm-dd')-LASTUPDTIME)<0  and
    (LAST_DAY(to_date('2005-5-1','YYYY-mm-dd'))-LASTUPDTIME)>0

posted @ 2005-08-06 21:20 月亮 阅读(2198) | 评论 (1)编辑 收藏

抱着老板的心态去打工

这是我的一个朋友写的,转给大家看看。

 从某种意义上来说,打工真是害人不浅,长期的打工固化了人的思维,淡化了人的责任感,扼杀了人的创新思维,没有成本概念,缺乏长远规划。最为关键的是,打工打得越久,看问题的视角就越悲观,自己也就越自卑。
   
  一群老板聚在一起,大家所交流的话题大多是商业环境,以及如何更好地发展生意等等。向对方展示的也是自己光辉灿烂的一面和发展的一面。
   
  一群打工者聚集在一起,牢骚往往占了多数,骂老板刻薄,埋怨工作量大且与收入不对称等等,很少有打工者对自己目前的状况满意的,向对方展示的也更多的是自己没有得到重用没有得到发挥的一面。当然,有牢骚未必是不重视自己的工作,因为“嫌货的才是买货的”。留心一下你就会发现,人在跳槽前反而异常平静,而成天把跳槽挂嘴边的人一般是那些一直做下去的人。
   
  为什么打工者会选择用语言而不是实干来获得心理平衡呢?这与打工者抱着一个什么样的心态在打工密不可分。
   
  笔者从1994年出道,打了四年工,跳出来自己开公司当老板,因根基不稳,一年后破产,又出来打工,四年后,又跳出来开公司当老板。在每次从打工者到老板,又由老板到打工者的转换过程中,都难免要经历一次耗时数月的心态调整和角色转换,逼着自己进行换位思考,每次的转换与脱一次皮也差不了多少。
   
  生意后来做大了,打算让太太来帮我接管我原来的那家公司,我自己重开一家,可太太打了八年工,接管公司后却把公司搞得乱七八糟。追查原因,原来太太还是按照打工的那一套在管理公司,我又足足花了两年时间来帮助太太实现由一个打工者向老板的转换。由此想到,如今报纸杂志电视上招商广告到处飞,好像有点资本就可以当老板了,好像老板可以速成?其实这就是许多创业以失败告终的原因。
   
  根据自己在老板与打工者角色之间不断转换的过程,我总结出以下老板与打工者心态的几点不同:
   
  长远目标与短期行为
   
  作为一个真正意义上的老板,知道自己最终想要什么,要达到目标需要经过哪些过程,具备长远眼光,拥有战略意识。而作为打工者,着眼点也就是当前这两三年,往往第一考虑的还是安全感,如何保住现有的饭碗,自然不会想得太远,也不会太高。而且,很少有打工者能进行换位思考,站到老板的角度去看问题和考虑问题。也就造成很多打工者很难与老板沟通。
   
  解决问题与完成工作
   
  老板对一件工作的完成定义是指把某件事彻底被解决,今天能搞定的一定不拖到明天。而打工者会习惯性地把工作按照天数来分解,每天只完成部分工作,下班时间一到心里就习惯性地想回家,剩下的工作明天再做,在公司里多待一分钟都不愿意。
   
  单个环节与整个系统
   
  打工者接到一个指派工作任务后,进行处理或是分解后转交给其他同事,然后在他看来,这事就差不多算完了,反正他负责的这块已经做完了,至于转交出去的工作是否被保质保量按时完成,那就不是他要操心的范围了。长此以往,许多打工者已经习惯只管自己的二亩三分地,严重缺少整体系统概念。而老板常常看的是整个任务的完成。
   
  推脱责任与承担失败
   
  在一个企业或是公司里,我们最常见到的就是在出现事故后,老板要追查责任人,大家异常统一、步调一致地互相推卸责任,极少有人会站出来承认自己工作的不足。打工打久了,遇到问题首先想到的是回避,然后就是设法推给别人。这样一来,打工者也就愈加不可能从失败和失利中学习、吸取教训。其实,老板们的成长就是从一个个自己承担失败,并从中总结分析了问题原因所在、积累经验而来的。
   
  个人意识与联合力量
   
  很多的打工者脑海中都存在着个人英雄主义,总希望在一些事情上表露一下,在老板面前表表功,为了不被其他同事抢了功劳,所以有时候就会冒一定的风险(当然是以公司的资源为成本的)一个人单枪匹马干点什么出来,当然,要是出了娄子,最后还得由公司承担,很少有打工者们会从降低成本及风险、或是提高效率的角度出发,去主动联合其他同事,共同完成某项任务。
   
  大手大脚与成本概念
   
  作为老板,公司的每一分钱的支出都会算作是成本,省下来的就是利润,所以,精打细算是许多老板的习惯性思维和行为。而打工者们却是大方得很,反正公司的资产是老板的,只要自己工作方便顺手,浪费点又算什么,以至于许多打工者在自己做老板的时候,还改变不了在打工时养成的大手大脚的习惯。
   
  办事一条线和思维多样化
   
  条条大路通罗马,完成工作不止一种方法,但打工者长期打工生涯下来,已经习惯了用单一思维去考虑问题,A事就用A类解决办法,B事就用B类解决办法,很少会去用超越性的思维来从多角度多方向来探讨问题的解决办法。
   
  从某种意义上来说,打工真是害人不浅,长期的打工固化了人的思维,淡化了人的责任感,扼杀了人的创新思维,没有成本概念,缺乏长远规划。最为关键的是,打工打得越久,看问题的视角就越悲观,自己也就越自卑。
   
  所以提醒各位,即使一时不能当老板,也要抱着老板的心态去打工

posted @ 2005-07-10 22:22 月亮 阅读(286) | 评论 (0)编辑 收藏

成为有钱人的25种方法

“嫁个有钱人”不如自己成为有钱人,你想发财吗?你知道如何成为有钱人吗?

1、做你真正感兴趣的事——你会花很多时间在上面,因此你一定要感兴趣才行,如果不是这样的话,你不愿意把时间花在上面,就得不到成功。

2、自己当老板。为别人打工,你绝不会变成巨富,老板一心一意地缩减开支,他的目标不是使他的职员变成有钱人。

3、提供一种有实效的服务,或一种实际的产品。你要以写作、绘画或作曲变成百万富翁的机会可以说是无限小,而你要在营造业、房地产、制造业发大财的机会比较大。记住,出版商赚的钱比作家多得多。

4、如果你坚持要用自己的灵感来创业?最好选择娱乐业,在这方面,发财的速度相当快,流行歌曲和电视最理想。

5、不论你是演员或商人,尽量增加你的观众。在小咖啡馆唱歌的人,所赚的钱一定比不上替大唱片公司灌唱片的人,地方性的商人,不会比全国性的商人赚的钱多。

6、找出一种需要,然后满足它。社会越变越复杂,人们所需要的产品和服务越来越多,最先发现这些需求而且满足他们的人,是改进现有产品和服务的人,也是最先成为富翁的人。

7、不要不敢采用不同的方式——新的方法和新产品,会造成新的财富。但必须确定你的新方法比旧方法更理想,你的新方法必
想致富,请栽摇钱 引爆数码影像!
中华川菜火锅大联 加盟乐可可天天乐

须增进产品外观、效率、品质、方便或者降低成本。

8、如果你受过专业教育,或者有特殊才能,充分利用它。如果你烧得一手好菜,而却要去当泥水匠,那就太笨了。

9、在你着手任何事情之前,仔细地对周围的情形研究一番。政府机关和公共图书馆,可以提供不少资料,先做研究,可以节省你不少时间和金钱。

10、不要一直都想着发大财,不如你想想如何改进你的事业,您应该常常问自己的是:“我如何改良我的事业?”如何使事业进行顺利,财富就会跟着而来。

11、可能的话,进行一种家庭事业,这种方法可以减少费用,增进士气,利润的分配很简单,利润能够得到充分的利用,整个事业控制也较容易。

12、尽可能减少你的费用,但不能牺牲你的品质,否则的话,你等于是在慢性自杀,赚钱的机会不会大。

13、跟同行的朋友维持友谊——他们可能对你很有帮助。

14、把尽量多的时间花在事业上。一天12小时、一星期6天是最低要求,一天14小时到18小时很平常,一星期工作7天最好了。你必须先牺牲家庭和社会上的娱乐,直到你事业站稳为止。也只有到那时候,你才能把责任分给别人。

15、不要不敢自己下决心。听听别人的赞美和批评,但你自己要下决心。

16、不要不敢说实话。拐弯抹角,只会浪费时间,心里想什么就说什么,而且要尽可能地直截了当地、明确地说出来。

17、不要不敢承认自己的错误。犯了错误并不是一种罪行,犯错不改才是罪过。

18、不要因为失败就裹足不前。失败是难免的,也是有价值的,从失败中,你会学到正确的方法论。

19、不要在不可行的观念上打转。一发现某种方法行不通,立即把它放弃。世界上有无数的方法,把时间浪费在那些不可行的方法上是无可弥补的损失。

20、不要冒你承担不起的风险。如果你损失10万元,若损失得起的话,就可以继续下去,但如果你赔不起5万元,而一旦失败的话,你就完蛋了。

21、一再投资,不要让你的利润空闲着,你的利润要继续投资下去,最好投资别的事业或你控制的事业上,那样,才能钱滚钱,替你增加好几倍的财富。

22、请一位高明的律师——他会替你节约更多的金钱和时间,比起你所给予的将要多的多。

23、请一位精明的会计师。最初的时候,你自己记账,但除非你本身是个会计师,你还是请一位精明的会计师,可能决定你的成功和失败——他是值得你花钱的。

24、请专家替你报税。一位机灵的税务专家,可又替你免很多的税。

25、好好维持你的健康和你的平静心灵——否则的话,拥有再多的钱也没有什么意思。

posted @ 2005-06-23 12:09 月亮 阅读(278) | 评论 (0)编辑 收藏

阻碍成功的几个性格

多疑,敏感,天真,犹豫不决,胆怯,多虑

-如果有就赶快克服它。

 

posted @ 2005-06-23 11:42 月亮 阅读(247) | 评论 (0)编辑 收藏

办公室中的省时小秘诀

1.了解你的精力充沛期。通常人们在早晨9点左右工作效率最高,可以把最困难的工作放到这时来完成。

  2.集中一天中的头两个小时来处理手头的工作并不接电话、不开会、不受打扰。这样可以事半功倍。

  3.立刻回复重要的邮件,将不重要的丢弃。若任它们积累成堆,反而更费时间。

  4.做个任务清单,将所有的项目和约定记在效率手册中。手头一定要带着效率手册以帮助自己按计划行事。

  5.学会高效地利用零碎时间,用来读点东西或是构思一个文件,不要发呆或做白日梦。

  6.把琐碎的工作写在单子上,以便有零碎时间时马上去做。

  7.并非每件工作都值得精工细做,有些事只要过得去就可以了。一遍又一遍地写些琐碎的备忘录不是高效利用时间的做法。

  8.减少回电话的时间。如果你需要传递的只是一个信息,不妨在工作以外的时间在录音电话上留言,或是发个电子邮件。

  9.如果有人在电话中喋喋不休地讲话,你可以礼貌地结束电话。

  10.对可能打来的电话做到心中有数,这样在你接到所期待的电话后便可迅速找到所需要的各种材料,不必当时乱翻乱找。

  11.学习上网高效搜寻的技能,以节省上网查询的时间。把你经常要浏览的网站收集起来以便随时找到。

  12.用国际互联网简化商业旅行的安排。多数饭店和航线可以网上查询和预订。

  13.只要情况允许就可委派别人分担工作。事必躬亲会使自己疲惫不堪,而且永远也做不完。不妨请同事帮忙,或让助手更努力地投入。

  14.做个灵活的日程表,当你需要时便可以忙中偷闲。例如,在中午加班,然后早一小时离开办公室去健身,或是每天工作10个小时,然后用星期五来赴约会、看医生。

  15.在离开办公室之前开列次日工作的清单,这样第二天早晨一来便可以全力以赴。

posted @ 2005-06-22 10:22 月亮 阅读(241) | 评论 (0)编辑 收藏

关于Java中方法重载的问题

Java中支持方法名相同,但是方法参数不同而自动去选择执行哪一个方法,如print(int i)和print(String str),虽然方法名相同,但是参数不同。象这里的int和String 参数差异比较大所以看起来这种重载没什么差别,但是如果是类型差别不大, 会出现什么情况呢?

   看下面的代码:

    public void f(float i){
        System.out.println("float");
    }

    public viod f(double i){
       System.out.println("double");
   }

    那么执行 f(5)会输出什么呢?5是被认为是float类型还是double类型还是会报错呢?执行结果是 float 。原来在这种情况下,该数据类型能被转为一个较大的数据类型,比5较大的数据类型是float,其次才到double,所以输出结果是float。还有一个特殊的情况就是如果输入类型为char,如这里我们执行f('a'),

不要以为这会出错,其实是不会出错的,因为如果没有发现一个准确的char于它匹配,那么它就把这个char转换成int类型,如果没有int类型和它匹配,在去寻找较大的数据类型,这里它找到了float,所以这里执行flaot('a')输出的还是 float。

  下面再讨论另外一种情况,譬如说下面这种情况:

   定义了下面一个方法:

  public void f(int i){
    System.out.println("int ");
}

  如果执行f(100.99)会不会在这种数据类型大于这种重载方法期待的变量时会怎么处理呢?会不会把这种较大的数据类型缩小到期待的数据类型?编译一下,很遗憾出错了,在这种情况下是出错的。

这么快就12点半了,睡觉了~~~不然明天早晨爬不起来了。

posted @ 2005-06-10 00:20 月亮 阅读(361) | 评论 (0)编辑 收藏

Java中的"goto"语句

虽然Java中goto语句只是java的一个保留字,没有起任何作用,但是我今天在使用continue和break语句时,还是发现了其中又goto语句的影子。因为continue和break语句都支持跳到一个Label的位置。下面是具体的用法:

  inner:
  for( int  i = 0 ; i<3 ;i++ ){
   System.out.println("iiii===>"+i); 
   for( int j =0 ; j<5; j++ ){
    if( j == 1 )
      continue  inner;
    System.out.println("j===>"+j); 
   }
  }

上面一段语句的输出为

iiii===>0
j===>0
iiii===>1
j===>0
iiii===>2
j===>0

一般的 continue语句都是跳出当前循环,但是这个会跳出到标记inner的位置。

posted @ 2005-06-08 23:28 月亮 阅读(2219) | 评论 (2)编辑 收藏

Java对象比较

 

Java中检查两个对象是否相等,这个看起来很简单的事情但是实际做起来不一定是一个简单的事情。我们可能首先想到的是==运算符号,但是这个运算符真的能比较两个对象么?我们先看下面一段代码:

   public static void main(String [] argv ){

        Integer    A = new Integer(47);

       Integer     B = new Integer(47);

      System.out.println( A == B ) ;

     System.out.println( A != B );

}

可能你觉得输出的结果是true false ,但是结果正好相反,是:false,true。不要觉得奇怪,因为==实际比较的是两个对象的句柄,而不是对象的内容,所以 A==B输出为false,    而A != B  输出为false.

可能以为equals方法能帮我们解决这个问题,那么来试一下,

class Value {
  int i;
}

public class EqualsMethod2 {
  public static void main(String[] args) {
    Value v1 = new Value();
    Value v2 = new Value();
    v1.i = v2.i = 100;
    System.out.println(v1.equals(v2));
  }
} ///:~
结果输出的并不是我们所希望的true,而是false,这是因为类默认的equal方法是直接比较句柄的,而不是我们所希望的比较内容,所以我们不得不发现我们要比较两个类的内容我们不得不在类中重写equal()方法来实现比较两个类的内容。

 

posted @ 2005-06-08 21:26 月亮 阅读(445) | 评论 (0)编辑 收藏

Java编程规则(转自CSDN)

原出处:http://dev.csdn.net/article/20/20614.shtm

(1) 类名首字母应该大写。字段、方法以及对象(句柄)的首字母应小写。对于所有标识符,其中包含的所有单词都应紧靠在一起,而且大写中间单词的首字母。例如:
ThisIsAClassName
thisIsMethodOrFieldName
若在定义中出现了常数初始化字符,则大写static final基本类型标识符中的所有字母。这样便可标志出它们属于编译期的常数。
Java包(Package)属于一种特殊情况:它们全都是小写字母,即便中间的单词亦是如此。对于域名扩展名称,如com,org,net或者edu等,全部都应小写(这也是Java 1.1和Java 1.2的区别之一)。

(2) 为了常规用途而创建一个类时,请采取“经典形式”,并包含对下述元素的定义:

equals()
hashCode()
toString()
clone()(implement Cloneable)
implement Serializable

(3) 对于自己创建的每一个类,都考虑置入一个main(),其中包含了用于测试那个类的代码。为使用一个项目中的类,我们没必要删除测试代码。若进行了任何形式的改动,可方便地返回测试。这些代码也可作为如何使用类的一个示例使用。

(4) 应将方法设计成简要的、功能性单元,用它描述和实现一个不连续的类接口部分。理想情况下,方法应简明扼要。若长度很大,可考虑通过某种方式将其分割成较短的几个方法。这样做也便于类内代码的重复使用(有些时候,方法必须非常大,但它们仍应只做同样的一件事情)。

(5) 设计一个类时,请设身处地为客户程序员考虑一下(类的使用方法应该是非常明确的)。然后,再设身处地为管理代码的人考虑一下(预计有可能进行哪些形式的修改,想想用什么方法可把它们变得更简单)。
(6) 使类尽可能短小精悍,而且只解决一个特定的问题。下面是对类设计的一些建议:
■一个复杂的开关语句:考虑采用“多形”机制
■数量众多的方法涉及到类型差别极大的操作:考虑用几个类来分别实现
■许多成员变量在特征上有很大的差别:考虑使用几个类

(7) 让一切东西都尽可能地“私有”——private。可使库的某一部分“公共化”(一个方法、类或者一个字段等等),就永远不能把它拿出。若强行拿出,就可能破坏其他人现有的代码,使他们不得不重新编写和设计。若只公布自己必须公布的,就可放心大胆地改变其他任何东西。在多线程环境中,隐私是特别重要的一个因素——只有private字段才能在非同步使用的情况下受到保护。

(8) 谨惕“巨大对象综合症”。对一些习惯于顺序编程思维、且初涉OOP领域的新手,往往喜欢先写一个顺序执行的程序,再把它嵌入一个或两个巨大的对象里。根据编程原理,对象表达的应该是应用程序的概念,而非应用程序本身。

(9) 若不得已进行一些不太雅观的编程,至少应该把那些代码置于一个类的内部。

(10) 任何时候只要发现类与类之间结合得非常紧密,就需要考虑是否采用内部类,从而改善编码及维护工作(参见第14章14.1.2小节的“用内部类改进代码”)。

(11) 尽可能细致地加上注释,并用javadoc注释文档语法生成自己的程序文档。

(12) 避免使用“魔术数字”,这些数字很难与代码很好地配合。如以后需要修改它,无疑会成为一场噩梦,因为根本不知道“100”到底是指“数组大小”还是“其他全然不同的东西”。所以,我们应创建一个常数,并为其使用具有说服力的描述性名称,并在整个程序中都采用常数标识符。这样可使程序更易理解以及更易维护。

(13) 涉及构建器和异常的时候,通常希望重新丢弃在构建器中捕获的任何异常——如果它造成了那个对象的创建失败。这样一来,调用者就不会以为那个对象已正确地创建,从而盲目地继续。

(14) 当客户程序员用完对象以后,若你的类要求进行任何清除工作,可考虑将清除代码置于一个良好定义的方法里,采用类似于cleanup()这样的名字,明确表明自己的用途。除此以外,可在类内放置一个boolean(布尔)标记,指出对象是否已被清除。在类的finalize()方法里,请确定对象已被清除,并已丢弃了从RuntimeException继承的一个类(如果还没有的话),从而指出一个编程错误。在采取象这样的方案之前,请确定finalize()能够在自己的系统中工作(可能需要调用System.runFinalizersOnExit(true),从而确保这一行为)。

(15) 在一个特定的作用域内,若一个对象必须清除(非由垃圾收集机制处理),请采用下述方法:初始化对象;若成功,则立即进入一个含有finally从句的try块,开始清除工作。

(16) 若在初始化过程中需要覆盖(取消)finalize(),请记住调用super.finalize()(若Object属于我们的直接超类,则无此必要)。在对finalize()进行覆盖的过程中,对super.finalize()的调用应属于最后一个行动,而不应是第一个行动,这样可确保在需要基础类组件的时候它们依然有效。

(17) 创建大小固定的对象集合时,请将它们传输至一个数组(若准备从一个方法里返回这个集合,更应如此操作)。这样一来,我们就可享受到数组在编译期进行类型检查的好处。此外,为使用它们,数组的接收者也许并不需要将对象“造型”到数组里。

(18) 尽量使用interfaces,不要使用abstract类。若已知某样东西准备成为一个基础类,那么第一个选择应是将其变成一个interface(接口)。只有在不得不使用方法定义或者成员变量的时候,才需要将其变成一个abstract(抽象)类。接口主要描述了客户希望做什么事情,而一个类则致力于(或允许)具体的实施细节。

(19) 在构建器内部,只进行那些将对象设为正确状态所需的工作。尽可能地避免调用其他方法,因为那些方法可能被其他人覆盖或取消,从而在构建过程中产生不可预知的结果(参见第7章的详细说明)。

(20) 对象不应只是简单地容纳一些数据;它们的行为也应得到良好的定义。

(21) 在现成类的基础上创建新类时,请首先选择“新建”或“创作”。只有自己的设计要求必须继承时,才应考虑这方面的问题。若在本来允许新建的场合使用了继承,则整个设计会变得没有必要地复杂。

(22) 用继承及方法覆盖来表示行为间的差异,而用字段表示状态间的区别。一个非常极端的例子是通过对不同类的继承来表示颜色,这是绝对应该避免的:应直接使用一个“颜色”字段。

(23) 为避免编程时遇到麻烦,请保证在自己类路径指到的任何地方,每个名字都仅对应一个类。否则,编译器可能先找到同名的另一个类,并报告出错消息。若怀疑自己碰到了类路径问题,请试试在类路径的每一个起点,搜索一下同名的.class文件。

(24) 在Java 1.1 AWT中使用事件“适配器”时,特别容易碰到一个陷阱。若覆盖了某个适配器方法,同时拼写方法没有特别讲究,最后的结果就是新添加一个方法,而不是覆盖现成方法。然而,由于这样做是完全合法的,所以不会从编译器或运行期系统获得任何出错提示——只不过代码的工作就变得不正常了。

(25) 用合理的设计方案消除“伪功能”。也就是说,假若只需要创建类的一个对象,就不要提前限制自己使用应用程序,并加上一条“只生成其中一个”注释。请考虑将其封装成一个“独生子”的形式。若在主程序里有大量散乱的代码,用于创建自己的对象,请考虑采纳一种创造性的方案,将些代码封装起来。

(26) 警惕“分析瘫痪”。请记住,无论如何都要提前了解整个项目的状况,再去考察其中的细节。由于把握了全局,可快速认识自己未知的一些因素,防止在考察细节的时候陷入“死逻辑”中。

(27) 警惕“过早优化”。首先让它运行起来,再考虑变得更快——但只有在自己必须这样做、而且经证实在某部分代码中的确存在一个性能瓶颈的时候,才应进行优化。除非用专门的工具分析瓶颈,否则很有可能是在浪费自己的时间。性能提升的隐含代价是自己的代码变得难于理解,而且难于维护。

(28) 请记住,阅读代码的时间比写代码的时间多得多。思路清晰的设计可获得易于理解的程序,但注释、细致的解释以及一些示例往往具有不可估量的价值。无论对你自己,还是对后来的人,它们都是相当重要的。如对此仍有怀疑,那么请试想自己试图从联机Java文档里找出有用信息时碰到的挫折,这样或许能将你说服。

(29) 如认为自己已进行了良好的分析、设计或者实施,那么请稍微更换一下思维角度。试试邀请一些外来人士——并不一定是专家,但可以是来自本公司其他部门的人。请他们用完全新鲜的眼光考察你的工作,看看是否能找出你一度熟视无睹的问题。采取这种方式,往往能在最适合修改的阶段找出一些关键性的问题,避免产品发行后再解决问题而造成的金钱及精力方面的损失。

(30) 良好的设计能带来最大的回报。简言之,对于一个特定的问题,通常会花较长的时间才能找到一种最恰当的解决方案。但一旦找到了正确的方法,以后的工作就轻松多了,再也不用经历数小时、数天或者数月的痛苦挣扎。我们的努力工作会带来最大的回报(甚至无可估量)。而且由于自己倾注了大量心血,最终获得一个出色的设计方案,成功的快感也是令人心动的。坚持抵制草草完工的诱惑——那样做往往得不偿失。

(31) 可在Web上找到大量的编程参考资源,甚至包括大量新闻组、讨论组、邮寄列表等。下面这个地方提供了大量有益的链接:

posted @ 2005-06-08 16:38 月亮 阅读(222) | 评论 (0)编辑 收藏

Java对象操作(自己体会,不一定说的正确,但是都是在程序中测试)

  Java中c中的指针的概念,但是我在使用中还是碰到过一些问题,如我把一个一个对象A赋值给对象B时,这两个对象有一个改变,那么另外一个也相应的改变。下面分别谈谈这可能发生问题的几种情况:

<一>从“一个对象到另一个对象的赋值”,如:

        Class  A = new Class();

       Class  B  = A;

       这种情况实际把句柄从一个地方复制到另外一个地方,这种情况下对象B和A实际指向的是同一个句柄,更新B会影响到A,同样更新A也会影响到B。

<二>把对象作为方法的参数传递到一个方法中。Java方法的参数传递可以分成两种:一种是值传递,这种一般是简单的数据类型,如int,long,double,char这些等;一种类似是c中的引用传递,就是把对象作为一个引用传递给方法参数,在这种情况下,在方法中把这个传入的参数对象改变,那么相应的传入这个参数引用的对象也相应的改变。如:

     Number A = new Number();
     A.num   = 9;
     test(A);

     方法定义:

    public  void   test(Number n){
      n.num = 99;
    }

   那么A的num值会变成99.

<三>;把对象保存在ArrayList中.如果把一个对象保存在一个AyyayList中,如果这个对象再发生改变,那么在这个ArrayList中保存的对象也会改变,说白了还是两个还是公用同一个句柄.如:

   Number A = new Number();
     A.num = 100;
     java.util.ArrayList list = new ArrayList();
     list.add(A);
     A.num = 999;
     Number B = (Number)list.get(0);
     System.out.println(B.num);

那么输出为999,对象A的更改影响到了ArrayList中的保存的对象.

 

posted @ 2005-06-08 00:19 月亮 阅读(269) | 评论 (0)编辑 收藏

人生就像一碗蔬菜汤

你看过老鹰吗?咱们生活在都市的人,大概很少有机会看到老鹰。根据鸟类生态学家的研究,老鹰是一种奇特的飞禽,因为它们都把窝巢筑在树梢,或是悬崖陡岩上,通用动物很难直接攻击它。

  可是,老鹰是怎么搭筑窝巢的呢?生态学家用望远镜仔细观察后发现,母鹰先用尖嘴衔着一些荆棘放置在底层,再叼来一些尖锐的小石子铺放在荆棘上面。乍看之下,总觉得用锐利的小石子当材料来筑巢,是很突兀、怪异的,这怎么能筑出一个温暖、舒适的窝巢呢?不过,母鹰后来又衔一些枯草、羽毛或兽皮覆盖在小石子上,做成一个能孵蛋的窝。

  小鹰孵化、出生后,住在窝巢里,母鹰按时叼回来小虫、肉食,喂入雏鹰嗷嗷待哺的小嘴中;母鹰天天供应食物,也细心保护,以防敌人入侵。后来,小鹰慢慢长大、羽毛渐丰,这时,母鹰认为,该是小鹰学习"自我独立"的时候了!

  可是,有什么办法能让小鹰不再眷恋始终被母鹰呵护、舒适无比的窝巢呢?有的,母鹰开始"搅动窝巢",让巢上的枯草、羽毛掉落,而暴露出尖锐的小石子和荆棘;小鹰被刺痛得哇哇叫,可是母鹰又很无情地加以驱逐、挥赶,小鹰只好忍痛振起双翅,离巢他飞。

  母鹰残忍、无情吗?不,母鹰深爱着它生养的小鹰!

  但是,母鹰更渴望它疼爱的小鹰能成为四处翱翔的飞鹰,因此,必须无情地逼着小鹰飞离舒适的窝,勇敢地学习独立;即使小鹰在刚开始跌跌撞撞,母鹰仍偷偷地在旁照顾看护它,直到小鹰能展翅高飞、直上青天!

  我在美国念博士班时,常搭飞机来回美台两地。有一次,我匆忙地赶上台北飞往旧金山的班机,查找座位后,发现身旁已经坐着一位30来岁的小姐。她身穿长裤,对着我微微一笑。漫长的飞行,我和她开始闲聊。她说,小时候家穷,父母又离异,所以国小毕业后就没再读书,只好跟人家学做裁缝;20多年过去了,现在经济能力好转,虽然想多念点书,可是没学历,不能念大学,于是只好趁暑假时间到美国念暑期美语学校,藉此拓展视野。

  这小姐脸庞清秀,不疾不徐地对我说:"我们客家人有一句谚语━━穷人莫断猪,富人莫断书;我啊,现在不是穷人了,但也不是什么富人,只是觉得自己必须多读点书,毕竟人生不像录影带、录音带,可以倒带重来,所以我希望尽可能地多充实自己!"

  聊着聊着,飞机已经飞行了3小时左右,这时,她礼貌地对着坐在走道旁的我说:"对不起,可不可以借我过一下,我想上洗手间?""噢,好!"我说,随即起身让她走过。

  只见这小姐用手扭转一下长裤里的硬硬东西,然后慢慢地站起来……她一跛一跛地、缓缓地从我眼前走过,再跛着脚,走向前端的盥洗室。天哪,身躯娇小的她,竟是一位小儿麻痹患者,她宽松的长裤里,装着的是支撑她站起来走路的铁鞋!

  当她走回座位时,我对她说:"你可以请空姐帮你安排前面好一点的座位呀!""不用啦!我已经习惯了,这小问题难不倒我!"她笑笑地对我说:"到美国念书3个月,要自己解决的问题还很多呢!"

  我常在想,有时,小鹰不一定都有母鹰喂食、呵护,也不一定会有同样残酷无情的母鹰逼它离巢他飞,但是孤苦无依的小鹰必须懂得━━要含泪坚强地站起来,自己飞、不断地飞,飞往属于自己的一片晴空与蓝天。

  其实,人生就如同"一大碗蔬菜汤",如果没经过搅动,鲜美好料就会"一直沉在碗底"。就像小鹰一样,母鹰无情地搅动窝巢,才逼得它必须独立展翅飞翔;可是,它不能抢劫超商、不能跳楼自杀,还是必须靠自己"独立更生",才有食物吃啊!人,似乎很少听说因为太勤劳、流汗太多,而被汗水淹没的!

  我们必须辛勤地"搅动自己",让鲜美的"蔬菜好料"浮现━━让内在的才华、能力美丽呈现。

  所以,告诉自己━━"我,一定要做最棒的我!"

posted @ 2005-06-07 16:48 月亮 阅读(375) | 评论 (1)编辑 收藏

关于文档的作用

       今天看了一篇文章,觉得很有启发。一个好的程序员不只是要写出好的代码,而且要学会写写文档和与别人交流,如果不能写文档和与别人交流,那么再好的代码别人也无法看懂。

        还有可能是自己的一个弊病--自己感兴趣的东西自己就喜欢做,但是自己不喜欢的东西就不喜欢做,但是工作中不可能都是自己喜欢的东西,喜欢的东西也要做好,那么才能是一个合格的程序员。

posted @ 2005-06-06 20:17 月亮 阅读(158) | 评论 (0)编辑 收藏

abstract和interface类的区别和共同点

* 1.定义方式的不同:
 *   <1>abstract类定义:
 *      public abstract class test{
 *          abstract void method1();
 *          abstarct void method2();
 *      }
 *   <2>interface类定义:
 *     public interface test{
 *         void method1();
 *         void method2();
 *     }
 * 2.abstract class类是表示一种继承关系,一个类只能继承一个abstract类,而一个类可以通过implements实现
 *   多个接口.
 *
 * 3.abstract类我们可以定义默认的方法,如可以在里面定义一个方法:
 *   public abstract class test{
 *          abstract void method1();
 *          abstarct void method2();
 *          public void print(){
 *            System.out.println("print");
 *          }
 *      }
 *   但是interface里面的方法都不能有body.
 *
 * 4.在Interface类中,所有的数据成员都是静态的不能被修改的。
 *   而abstract类可以有自己的数据成员

posted @ 2005-06-02 14:59 月亮 阅读(351) | 评论 (0)编辑 收藏

Struct学习笔记1

昨天开始学习structs,计划用2周来大致上把握Structs,大致觉得structs的优势在于提高web开发的速度,尤其是在大型的项目中,但是前期的设计可能要花很多的时间来计划每个页面对应到哪个ActionForm和Action,计划好每个页面跳转的页面。觉得其中主要的思想就是MVC,这种方式的好处就是:

一。多个视图可以公用一个模型,如同一个web程序可能有多种用户界面,浏览器或wap。把逻辑层和表示层分开。提高代码的重用性。

二。控制器和视图保持独立,要更改控制,只要去更改控制器部分就可以了,与视图无关。



对例子看了一下实现的,觉得大致流程是这样的:

从页面上的标记.do的名称,从struct-config.xml中取出对应该Form处理的ActionForm,执行取变量或Validate之后,再转给Action来处理,执行完毕后再跳转到下一个页面。



 加油,一定要2周搞定它.

posted @ 2005-06-01 00:11 月亮 阅读(418) | 评论 (0)编辑 收藏