??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲中文字幕无码中文字,亚洲国产精品第一区二区三区,亚洲一区精品中文字幕http://www.tkk7.com/apple0668/TDD,Agile,Scrum,Core Java,J2EE,Investment Blankzh-cnFri, 09 May 2025 17:14:28 GMTFri, 09 May 2025 17:14:28 GMT60Ehcache集群Ҏ(gu)http://www.tkk7.com/apple0668/archive/2015/03/18/423596.htmlapple0668apple0668Wed, 18 Mar 2015 14:05:00 GMThttp://www.tkk7.com/apple0668/archive/2015/03/18/423596.htmlhttp://www.tkk7.com/apple0668/comments/423596.htmlhttp://www.tkk7.com/apple0668/archive/2015/03/18/423596.html#Feedback0http://www.tkk7.com/apple0668/comments/commentRss/423596.htmlhttp://www.tkk7.com/apple0668/services/trackbacks/423596.html1.是RMI方式点对Ҏ(gu)式,手动方式Q这U方式网上搜索结果大部分都可以用Q优点同步可靠,唯一~点是部v多个应用需要改配置文gQ这样增加部|的复杂性?br />2.是RMI的广播Ş式,自动方式Q指定相兛_播的IP范围和端口,优点部v应用不用攚w|文Ӟ多个应用同一套配|文Ӟ~点Q广播方式不E_?br />3.通过JGOUP方式Q这U方式需要额外增加jgoup的jar包和jgroupreplication包,|上搜烦90%配置都是抄来抄去不可用,最苦逼的是连ehcache官网的配|都不可用,最l还是terracotta论坛扑ֈ相关解决Ҏ(gu)Q优点,多个应用公用一套配|文Ӟ集群E_Q缺点,需要增加额外的支持jar包?img src ="http://www.tkk7.com/apple0668/aggbug/423596.html" width = "1" height = "1" />

apple0668 2015-03-18 22:05 发表评论
]]>
MongoDB安装手记http://www.tkk7.com/apple0668/archive/2012/07/07/382479.htmlapple0668apple0668Sat, 07 Jul 2012 14:11:00 GMThttp://www.tkk7.com/apple0668/archive/2012/07/07/382479.htmlhttp://www.tkk7.com/apple0668/comments/382479.htmlhttp://www.tkk7.com/apple0668/archive/2012/07/07/382479.html#Feedback0http://www.tkk7.com/apple0668/comments/commentRss/382479.htmlhttp://www.tkk7.com/apple0668/services/trackbacks/382479.htmlMongoDB是一个高性能Q开源,无模式的文档型数据库Q是当前NoSql数据库中比较热门的一U。它在许多场景下可用于替代传l的关系型数据库或键/值存储方式。Mongo使用C++开发?br />安装Q?br />软硬件环?br />-----------------------
pȝQwin7 64bit
数据库:Mongo-2.0.6
-----------------------
下蝲地址Q?a >http://www.mongodb.org/downloads
按照自己需要下载对应操作系l的数据库版本?br />目前׃我的?4pȝQ下载对?4位的数据库?br />
Step1Q解压MongoDB目录为C:\mongodb
Step2Q创建E:\MongoDB\dataQ指定数据库存储目录E:\MongoDB\dataQ操作如?br />C:\mongodb\bin\mongod --dbpath E:\MongoDB\data


试数据库是否安装成功:览器输?a href="http://localhost:27017/">http://localhost:27017/
l果Q?pre>You are trying to access MongoDB on the native driver port. For http diagnostic access, add 1000 to the port number 安装成功Q可以用MongoDBq行开发工作了?br />
然后q行mongo卛_q接到test数据库,你就可以q行数据操作。运行help昄帮助命o行?/span>
双击QC:\mongodb\bin\mongo.exe,输入help帮助命o



可以在命o行下面进行数据库操作了?br /> 

apple0668 2012-07-07 22:11 发表评论
]]>
M人都可以重构<转蝲>http://www.tkk7.com/apple0668/archive/2012/04/28/376978.htmlapple0668apple0668Sat, 28 Apr 2012 07:56:00 GMThttp://www.tkk7.com/apple0668/archive/2012/04/28/376978.htmlhttp://www.tkk7.com/apple0668/comments/376978.htmlhttp://www.tkk7.com/apple0668/archive/2012/04/28/376978.html#Feedback0http://www.tkk7.com/apple0668/comments/commentRss/376978.htmlhttp://www.tkk7.com/apple0668/services/trackbacks/376978.html原文Q?a >https://www.ibm.com/developerworks/cn/linux/opensource/os-ecref/
Z么重?

重构是指在不改变E序功能的前提下改变其结构。重构是一功能强大的技术,但是执行h需要倍加心才行。主要的危险在于可能在不l意中引入一些错误,其是在q行手工重构的时候更是如此。这U危险引发了寚w构技术的普遍批评Q当代码不会崩溃的时候ؓ什么要修改它呢Q?

(zhn)需要进行代码重构的原因可能有以下几个:传说中的W一个原因是Q需要承ؓ某个古老品而开发的q代久远的代码,或者突然碰到这些代码。最初的开发团队已l不在了。我们必d建增加了新特性的新版本YӞ但是q些代码已经无法理解了。新的开发队伍夜以日地工作Q破译代码然后映代码,l过大量的规划与设计之后Qh们将q些代码分割成碎片。历l重重磨难之后,所有这些东襉K按照新版本的要求归位了。这是英雄般的重构故事,几乎没有在经历了q些之后zȝ讲述q样的故事?/p>

q有一U现实一些的情况是项目中加入了新的需求,需要对设计q行修改。至于是因ؓ在最初的规划q程中失察,q是׃采用了P代式的开发过E(比如敏捷开发,或者是试驱动的开发)而在开发过E中有意引入需求,q两者ƈ没有实质性的区别。这L重构的规模要得多,其内容一般涉及通过引入接口或者抽象类来更改类的承关p,以及对类q行分割和重新组l,{等?/p>

重构的最后一个原因是Q当存在可用的自动重构工hQ可以有一个用来预先生成代码的快捷方式——好比在(zhn)无法确定如何拼写某个单词的时候,可以用某U拼写检查工兯入这个单词。比如说Q?zhn)可以用这U^淡无奇的重构Ҏ(gu)生成 getter ?setter Ҏ(gu)Q一旦熟(zhn)了q样的工P它就可以为?zhn)节省很多的时间?/p>

Eclipse 的重构工h意进行英雄的重?#8212;—适合q种规模的工具几乎没?#8212;—但是不论是否用到敏捷开发技术,Eclipse 的工具对于一般程序员修改代码的工作都h无法衡量的h(hun)倹{毕竟Q何复杂的操作只要能够自动q行Q就可以不那么烦闷了。只要?zhn)知?Eclipse 实现了什么样的重构工Pq理解了它们的适用情况Q?zhn)的生产力׃得到极大的提高?/p>

要降低对代码造成破坏的风险,有两U重要的Ҏ(gu)。第一U方法是对代码进行一套完全彻底的单元试Q在重构之前和之后都必须通过q样的测试。第二种Ҏ(gu)是用自动化的工hq行重构Q比如说 Eclipse 的重构特性?/p>

彻底的试与自动化重构l合h׃更加有效了,q样重构也就从一U神U的艺术变成了有用的日常工具。ؓ了增加新的功能或者改q代码的可维护性,我们可以在不影响原有代码功能的基上迅速且安全地改变其l构。这U能力会Ҏ(gu)设计和开发代码的方式产生极大的媄响,即便是?zhn)没有其l合到正式的敏捷Ҏ(gu)中也没有关系?/p>


Eclipse 中重构的cd

Eclipse 的重构工具可以分Z大类Q下面的序也就是这些工具在 Refactoring 菜单中出现的序Q:

  1. 对代码进行重命名以及改变代码的物理结构,包括对属性、变量、类以及接口重新命名Q还有移动包和类{?/li>
  2. 改变cMU的代码逻辑l构Q包括将匿名c{变ؓ嵌套c,嵌套类转变为顶U类、根据具体的cd建接口,以及从一个类中将Ҏ(gu)或者属性移到子cL者父cM?/li>
  3. 改变一个类内部的代码,包括局部变量变成类的属性、将某个Ҏ(gu)中选中部分的代码变成一个独立的Ҏ(gu)、以及ؓ属性生?getter ?setter Ҏ(gu)?/li>

q有几个重构工具q不能完全归入这三个U类Q特别是 Change Method SignatureQ不q在本文中还是将q个工具归入W三cR除了这U例外情况以外,本文下面几节都是按照上面的顺序来讨论 Eclipse 重构工具的?/p>


物理重组与重命名

昄Q?zhn)即便没有特别的工P也可以在文gpȝ中重命名文g或者是Ud文gQ但是如果操作对象是 Java 源代码文Ӟ(zhn)就需要编辑很多文Ӟ更新其中?import ?package 语句。与此类|用某U文本编辑器的搜索与替换功能也可以很Ҏ(gu)地给cR方法和变量重新命名Q但是这样做的时候必d分小心,因ؓ不同的类可能h名称怼的方法或者变量;要是从头到尾查项目中所有的文gQ来保证每个东西的标识和修改的正性,那可真够乏味的?

Eclipse ?Rename ?Move 工具能够十分聪明地在整个目中完成这L修改Q而不需要用Lq涉。这是因?Eclipse 可以理解代码的语义,从而能够识别出Ҏ(gu)个特定方法、变量或者类名称的引用。简化这一d有助于确保方法、变量和cȝ名称能够清晰地指C其用途?/p>

我们l常可以发现代码的名字不恰当或者o人容易误解,q是因ؓ代码与最初设计的功能有所不同。比方说Q某个用来在文g中查扄定单词的E序也许会扩展ؓ?Web 面中通过 URL 获取 InputStream 的操作。如果这一输入最初叫?file Q那么就应该修改它的名字Q以便能反映其新增的更加一般的Ҏ(gu),比方?sourceStream 。开发h员经常无法成功地修改q些名称Q因个过E是十分混ؕ和乏味的。这当然也会把下一个不得不对这些类q行操作的开发h员弄p涂?

要对某个 Java 元素q行重命名,只需要简单地?Package Explorer 视图中点击这个元素,或者从Java 源代码文件中选中q个元素Q然后选择菜单?Refactor > Rename。在对话框中输入新的名称Q然后选择是否需?Eclipse 也改变对q个名称的引用。实际显C出来的切内容与?zhn)所选元素的cd有关。比方说Q如果选择的属性具?getter ?setter Ҏ(gu)Q那么也可以同时更新这些方法的名称Q以反映新的属性。图1昄了一个简单的例子?

?1. 重命名一个局部变?/strong>
Renaming a local variable

像所有的 Eclipse 重构操作一P当?zhn)指定了全部用来执行重构的必要信息之后Q?zhn)可以点?Preview 按钮Q然后在一个对话框中对?Eclipse 打算q行哪些变更Q?zhn)可以分别否决或者确认每一个受到媄响的文g中的每一变更。如果?zhn)对?Eclipse 正确执行变更的能力有信心的话Q?zhn)可以只按?OK按钮。显Ӟ如果(zhn)不定重构到底做了什么事情,(zhn)就会想先预览一下,但是对于 Rename ?Move q样单的重构而言Q通常没有必要预览?

Move 操作?Rename 十分怼Q?zhn)选择某个 Java 元素Q通常是一个类Q,为其指定一个新位置Qƈ定义是否需要更新引用。然后,(zhn)可以选择 Preview查变更情况,或者选择 OK 立即执行重构Q如?所C?

?2. 类从一个包Ud另一个包
Moving a class

在某些^CQ特别是 WindowsQ,(zhn)还可以?Package Explorer 视图中通过单拖攄Ҏ(gu)类从一个包或者文件夹中移到另一个包或文件夹中。所有的引用都会自动更新?/p>


重新定义cȝ关系

Eclipse 中有大量的重构工P使?zhn)能够自动改变cȝ关系。这些重构工具ƈ没有 Eclipse 提供的其他工具那么常用,但是很有价|因ؓ它们能够执行非常复杂的Q务。可以说Q当它们用得上的时候,׃非常有用?/p>

提升匿名cM嵌套c?/span>

Convert Anonymous ClassQ{换匿名类Q和 Convert Nested TypeQ{换嵌套类Q这两种重构Ҏ(gu)比较怼Q它们都某个类从其当前范围Ud到包含这个类的范围上?/p>

匿名cL一U语法速写标记Q(zhn)能够在需要实现某个抽象类或者接口的地方创徏一个类的实例,而不需要显式提供类的名U。比如在创徏用户界面中的监听器时Q就l常用到匿名cR在清单1中,假设 Bag 是在其他地方定义的一个接口,其中声明了两个方法, get() ?set() ?


清单 1. Bag c?/strong>
 
      public class BagExample
{
   void processMessage(String msg)
   {
      Bag bag = new Bag()
      {
         Object o;
         public Object get()
         {
            return o;
         }
         public void set(Object o)
         {
            this.o = o;
         }
      };
      bag.set(msg);
      MessagePipe pipe = new MessagePipe();
      pipe.send(bag);
   }
}

当匿名类变得很大Q其中的代码难以阅读的时候,(zhn)就应该考虑这个匿名类变成严格意义上的c;Z保持装性(换句话说Q就是将它隐藏v来,使得不必知道它的外部cM知道它)Q?zhn)应该其变成嵌套c,而不是顶U类。?zhn)可以在这个匿名类的内部点击,然后选择 Refactor > Convert Anonymous Class to Nested 可以了。当出现认对话框的时候,个类输入名称Q比?BagImpl Q然后选择 Preview或?OK。这P代码变成了如清?所C的情Ş?


清单 2. l过重构?Bag c?/strong>
 
public class BagExample
{
   private final class BagImpl implements Bag
   {
      Object o;
      public Object get()
      {
         return o;
      }
      public void set(Object o)
      {
         this.o = o;
      }
   }
       
   void processMessage(String msg)
   {
     Bag bag = new BagImpl();
     bag.set(msg);
     MessagePipe pipe = new MessagePipe();
     pipe.send(bag);
   }
}

当?zhn)惌其他的类使用某个嵌套cLQConvert Nested Type to Top Level 很有用了。比方说Q?zhn)可以在一个类中用值对象,像上面?BagImpl c那栗如果?zhn)后来又决定应该在多个cM间共享这个数据,那么重构操作p从这个嵌套类中创建新的类文g。?zhn)可以在源代码文g中高亮选中cdUͼ或者在 Outline 视图中点ȝ的名UͼQ然后选择 Refactor > Convert Nested Type to Top LevelQ这样就实现了重构?

q种重构要求(zhn)ؓ装入实例提供一个名字。重构工具也会提供徏议的名称Q比?example Q?zhn)可以接受q个名字。这个名字的意思过一会儿清楚了。点?OK 之后Q外层类 BagExample ׃变成清单3所C的样子?


清单 3. l过重构?Bag c?/strong>
public class BagExample
{
   void processMessage(String msg)
   {
      Bag bag = new BagImpl(this);
      bag.set(msg);
      MessagePipe pipe = new MessagePipe();
      pipe.send(bag);
   }
}

h意,当一个类是嵌套类的时候,它可以访问其外层cȝ成员。ؓ了保留这U功能,重构q程一个装入类 BagExample 的实例放在前面那个嵌套类中。这是之前要求(zhn)输入名U的实例变量。同时也创徏了用于设|这个实例变量的构造函数。重构过E创建的新类 BagImpl 如清?所C?


清单 4. BagImpl c?/strong>
  
final class BagImpl implements Bag
{
   private final BagExample example;
   /**
    * @paramBagExample
    */
  BagImpl(BagExample example)
   {
      this.example = example;
      // TODO Auto-generated constructor stub
   }
   Object o;
   public Object get()
   {
      return o;
   }
   public void set(Object o)
   {
      this.o = o;
   }
}

如果(zhn)的情况与这个例子相同,不需要保留对 BagExample 的访问,(zhn)也可以很安全地删除q个实例变量与构造函敎ͼ?BagExample cM的代码改成缺省的无参数构造函数?

在类l承关系内移动成?/span>

q有两个重构工具QPush Down ?Pull UpQ分别实现将cL法或者属性从一个类Ud到其子类或父cM。假设?zhn)有一个名?Vehicle 的抽象类Q其定义如清?所C?


清单 5. 抽象?Vehicle c?/strong>
public abstract class Vehicle
{
   protected int passengers;
   protected String motor;
   
   public int getPassengers()
   {
      return passengers;
   }
   public void setPassengers(int i)
   {
      passengers = i;
   }
   public String getMotor()
   {
      return motor;
   }
   public void setMotor(String string)
   {
      motor = string;
   }
}

(zhn)还有一?Vehicle 的子c,cd?Automobile Q如清单6所C?


清单6. Automobile c?/strong>
public class Automobile extends Vehicle
{
   private String make;
   private String model;
   public String getMake()
   {
      return make;
   }
   public String getModel()
   {
      return model;
   }
   public void setMake(String string)
   {
      make = string;
   }
   public void setModel(String string)
   {
      model = string;
   }
}

h意, Vehicle 有一个属性是 motor 。如果?zhn)知道?zhn)将永远只处理汽车,那么q样做就好了Q但是如果?zhn)也允许出现划艇之cȝ东西Q那么?zhn)需要将 motor 属性从 Vehicle cM攑ֈ Automobile cM。ؓ此,(zhn)可以在 Outline 视图中选择 motor Q然后选择 Refactor > Push Down?

Eclipse q是明的Q它知道(zhn)不可能L单单Ud某个属性本w,因此q提供了 Add Required 按钮Q不q在 Eclipse 2.1 中,q个功能q不L能正地工作。?zhn)需要验证一下,看所有依赖于q个属性的Ҏ(gu)是否都推C下一层。在本例中,q样的方法有两个Q即?motor 怼?getter ?setter Ҏ(gu)Q如?所C?

?3. 加入所需的成?/strong>
Adding required members

在按q?OK按钮之后Q?motor 属性以?getMotor() ?setMotor() Ҏ(gu)׃Ud?Automobile cM。清?昄了在q行了这ơ重构之?Automobile cȝ情Ş?


清单 7. l过重构?Automobile c?/strong>
public class Automobile extends Vehicle
{
   private String make;
   private String model;
   protected String motor;
   public String getMake()
   {
      return make;
   }
   public String getModel()
   {
      return model;
   }
   public void setMake(String string)
   {
      make = string;
   }
   public void setModel(String string)
   {
      model = string;
   }
   public String getMotor()
   {
      return motor;
   }
   public void setMotor(String string)
   {
      motor = string;
   }
}

Pull Up 重构?Push Down 几乎相同Q当?Pull Up 是将cL员从一个类中移到其父类中,而不是子cM。如果?zhn)E后改变LQ决定还是把 motor Ud?Vehicle cMQ那么?zhn)也许׃用到q种重构。同样需要提醒?zhn)Q一定要认(zhn)是否选择了所有必需的成员?

Automobile cMh成员 motorQ这意味着(zhn)如果创建另一个子c,比方?Bus Q?zhn)p需要将 motor Q及其相x法)加入?Bus cM。有一U方法可以表CU关p,卛_Z个名?Motorized 的接口, Automobile ?Bus 都实现这个接口,但是 RowBoat 不实现?

创徏 Motorized 接口最单的Ҏ(gu)是在 Automobile 上?Extract Interface 重构。ؓ此,(zhn)可以在 Outline 视图中选择 Automobile Q然后从菜单中选择 Refactor > Extract Interface。?zhn)可以在弹出的对话框中选择(zhn)希望在接口中包含哪些方法,如图4所C?

?4. 提取 Motorized 接口
Motorized interface

点击 OK 之后Q接口就创徏好了Q如清单8所C?/p>
清单 8. Motorized 接口
public interface Motorized
{
   public abstract String getMotor();
   public abstract void setMotor(String string);
}

同时Q?Automobile 的类声明也变成了下面的样子:

public class Automobile extends Vehicle implements Motorized

使用父类

本重构工L型中最后一个是 User Supertyp Where Possible。想象一个用来管理汽车细帐的应用E序。它自始至终都?Automobile cd的对象。如果?zhn)惛_理所有类型的交通工P那么(zhn)就可以用这U重构将所有对 Automobile 的引用都变成?Vehicle 的引用(参看?Q。如果?zhn)在代码中?instanceof 操作执行了Q何类型检查的话,(zhn)将需要决定在q些地方适用的是原先的类q是父类Q然后选中W一个选项“Use the selected supertype in 'instanceof' expressions”?

?5. ?Automobile Ҏ(gu)其父c?Vehicle
Supertype

使用父类的需求在 Java 语言中经常出玎ͼ特别是在使用?Factory Method 模式的情况下。这U模式的典型实现方式是创Z个抽象类Q其中具有静态方?create() Q这个方法返回的是实Cq个抽象cȝ一个具体对象。如果需创徏的具体对象的cd依赖于实现的l节Q而调用类对实现细节ƈ不感兴趣的情况下Q可以用这一模式?


改变cd部的代码

最大一c重构是实现了类内部代码重组的重构方法。在所有的重构Ҏ(gu)中,只有q类Ҏ(gu)允许(zhn)引入或者移除中间变量,Ҏ(gu)原有Ҏ(gu)中的部分代码创徏新方法,以及为属性创?getter ?setter Ҏ(gu)?/p>

提取与内?/span>

有一些重构方法是?Extract q个词开头的QExtract Method、Extract Local Variable 以及Extract Constants。第一?Extract Method 的意思?zhn)可能已经猜到了,它根据(zhn)选中的代码创建新的方法。我们以清单8中那个类?main() Ҏ(gu)Z。它首先取得命o行选项的|如果有以 -D 开头的选项Q就其以名-值对的Ş式存储在一?Properties 对象中?


清单 8. main()
import java.util.Properties;
import java.util.StringTokenizer;
public class StartApp
{
   public static void main(String[] args)
   {
      Properties props = new Properties();
      for (int i= 0; i < args.length; i++)
      {
         if(args[i].startsWith("-D"))
         {
           String s = args[i].substring(2);
           StringTokenizer st = new StringTokenizer(s, "=");
            if(st.countTokens() == 2)
            {
              props.setProperty(st.nextToken(), st.nextToken());
            }
         }
      }
      //continue...
   }
}

一部分代码从一个方法中取出q放q另一个方法中的原因主要有两种。第一U原因是q个Ҏ(gu)太长Qƈ且完成了两个以上逻辑上截然不同的操作。(我们不知道上面那?main() Ҏ(gu)q要处理哪些东西Q但是从现在掌握的证据来看,q不是从其中提取Z个方法的理由。)另一U原因是有一D逻辑上清晰的代码Q这D代码可以被其他Ҏ(gu)重用。比方说在某些时候,(zhn)发现自己在很多不同的方法中都重复编写了相同的几行代码。那有可能是需要重构的原因了,不过除非真的需要重用这部分代码Q否则?zhn)很可能ƈ不会执行重构?

假设(zhn)还需要在另外一个地方解析名-值对Qƈ其攑֜ Properties 对象中,那么(zhn)可以将包含 StringTokenizer 声明和下面的 if 语句的这D代码抽取出来。ؓ此,(zhn)可以高亮选中q段代码Q然后从菜单中选择 Refactor > Extract Method。?zhn)需要输入方法名Uͼq里输入 addProperty Q然后验证这个方法的两个参数Q?Properties prop ?Strings 。清?昄?Eclipse 提取?addProp() Ҏ(gu)之后cȝ情况?


清单 9. 提取出来?addProp()
import java.util.Properties;
import java.util.StringTokenizer;
public class Extract
{
   public static void main(String[] args)
   {
      Properties props = new Properties();
      for (int i = 0; i < args.length; i++)
      {
         if (args[i].startsWith("-D"))
         {
            String s = args[i].substring(2);
            addProp(props, s);
         }
      }
   }
   private static void addProp(Properties props, String s)
   {
      StringTokenizer st = new StringTokenizer(s, "=");
      if (st.countTokens() == 2)
      {
         props.setProperty(st.nextToken(), st.nextToken());
      }
   }
}

Extract Local Variable 重构取出一D被直接使用的表辑ּQ然后将q个表达式首先赋值给一个局部变量。然后在原先使用那个表达式的地方使用q个变量。比方说Q在上面的方法中Q?zhn)可以高亮选中?st.nextToken() 的第一ơ调用,然后选择 Refactor > Extract Local Variable。?zhn)被提示输入一个变量名Uͼq里输入 key 。请注意Q这里有一个将被选中表达式所有出现的地方都替换成新变量的引用的选项。这个选项通常是适用的,但是对这里的 nextToken() Ҏ(gu)不适用Q因个方法(昄Q在每一ơ调用的时候都q回不同的倹{确认这个选项未被选中。参见图6?

?6. 不全部替换所选的表达?/strong>
Extract variable

接下来,在第二次调用 st.nextToken() 的地斚w复进行重构,q一ơ调用的是一个新的局部变?value 。清?0昄了这两次重构之后代码的情形?


清单 10. 重构之后的代?/strong>
private static void addProp(Properties props, String s)
   {
     StringTokenizer st = new StringTokenizer(s, "=");
      if(st.countTokens() == 2)
      {
         String key = st.nextToken();
         String value = st.nextToken();
        props.setProperty(key, value);
      }
   }

用这U方式引入变量有几点好处。首先,通过辑ּ提供有意义的名称Q可以得代码执行的d更加清晰。第二,代码调试变得更容易,因ؓ我们可以很容易地查表辑ּq回的倹{最后,在可以用一个变量替换同一表达式的多个实例的情况下Q效率将大大提高?/p>

Extract Constant ?Extract Local Variable 怼Q但是?zhn)必须选择静态常量表辑ּQ重构工具将会把它{换成静态的 final 帔R。这在将编码的数字和字W串从代码中去除的时候非常有用。比方说Q在上面的代码中我们?#8220;-D”q一命o行选项来定义名-值对。先?#8220;-D”高亮选中Q选择 Refactor > Extract ConstantQ然后输?DEFINE 作ؓ帔R的名U。重构之后的代码如清?1所C:


清单 11. 重构之后的代?/strong>
public class Extract
{
   private static final String DEFINE = "-D";
   public static void main(String[] args)
   {
      Properties props = new Properties();
      for (int i = 0; i < args.length; i++)
      {
         if (args[i].startsWith(DEFINE))
         {
            String s = args[i].substring(2);
            addProp(props, s);
         }
      }
   }
   // ...

对于每一U?Extract... cȝ重构Q都存在对应?Inline... 重构Q执行与之相反的操作。比方说Q如果?zhn)高亮选中上面代码中的变量 sQ选择 Refactor > Inline...Q然后点?OKQEclipse ׃在调?addProp() 的时候直接?args[i].substring(2) q个表达式,如下所C:

        if(args[i].startsWith(DEFINE))
         {
            addProp(props,args[i].substring(2));
         }

q样比用(f)时变量效率更高,代码也变得更加简要,至于q样的代码是易读q是含؜Q就取决于?zhn)的观点了。不q一般说来,q样的内嵌重构没什么值得推荐的地斏V?/p>

(zhn)可以按照用内嵌表达式替换变量的相同Ҏ(gu)Q高亮选中Ҏ(gu)名,或者静?final 帔RQ然后从菜单中选择 Refactor > Inline...QEclipse ׃用方法的代码替换Ҏ(gu)调用Q或者用帔R的值替换对帔R的引用?

装属?/span>

通常我们认ؓ对象的内部l构暴露出来是一U不好的做法。这也正?Vehicle cd其子c都h private 或?protected 属性,而用 public setter ?getter Ҏ(gu)来访问属性的原因。这些方法可以用两种不同的方式自动生成?

W一U生成这些方法的方式是?Source > Generate Getter and Setter 菜单。这会昄一个对话框Q其中包含所有尚未存在的 getter ?setter Ҏ(gu)。不q因U方式没有用新方法更新对q些属性的引用Q所以ƈ不算是重构;必要的时候,(zhn)必自己完成更新引用的工作。这U方式可以节U很多时_但是最好是在一开始创建类的时候,或者是向类中加入新属性的时候用,因ؓq些时候还不存在对属性的引用Q所以不需要再修改其他代码?

W二U生?getter ?setter Ҏ(gu)的方式是选中某个属性,然后从菜单中选择 Refactor > Encapsulate Field。这U方式一ơ只能ؓ一个属性生?getter ?setter Ҏ(gu)Q不q它?Source > Generate Getter and Setter 相反Q可以将对这个属性的引用改变成对新方法的调用?

例如Q我们可以先创徏一个新的简?Automobile c,如清?2所C?


清单 12. 单的 Automobile c?/strong>
public class Automobile extends Vehicle
{
   public String make;
   public String model;
}

接下来,创徏一个类实例化了 Automobile 的类Qƈ直接讉K make 属性,如清?3所C?


清单 13. 实例?Automobile
public class AutomobileTest
{
   public void race()
   {
      Automobilecar1 = new Automobile();
      car1.make= "Austin Healy";
      car1.model= "Sprite";
      // ...
   }
}

现在装 make 属性。先高亮选中属性名Uͼ然后选择 Refactor > Encapsulate Field。在弹出的对话框中输?getter ?setter Ҏ(gu)的名U?#8212;—如?zhn)所料,~省的方法名U分别是 getMake() ?setMake()。?zhn)也可以选择与这个属性处在同一个类中的Ҏ(gu)是l直接访问该属性,q是像其他类那样改用q些讉KҎ(gu)。(有一些h非常們֐于用这两种方式的某一U,不过y在这U情况下(zhn)选择哪一U方式都没有区别Q因?Automobile 中没有对 make 属性的引用。)

?. 装属?/strong>
Encapsulating a field

点击 OK之后Q?Automobile cM?make 属性就变成了私有属性,也同时具有了 getMake() ?setMake() Ҏ(gu)?

>


清单 14. l过重构?Automobile c?/strong>
public class Automobile extends Vehicle
{
   private String make;
   public String model;
   public void setMake(String make)
   {
      this.make = make;
   }
   public String getMake()
   {
      return make;
   }
}

AutomobileTest cM要进行更斎ͼ以便使用新的讉KҎ(gu)Q如清单15所C?


>清单 15. AutomobileTest c?/strong>
public class AutomobileTest
{
   public void race()
   {
      Automobilecar1 = new Automobile();
      car1.setMake("Austin Healy");
      car1.model= "Sprite";
      // ...
   }
}

改变Ҏ(gu)的签?/span>

本文介绍的最后一个重构方法也是最难以使用的方法:Change Method SignatureQ改变方法的{֐Q。这U方法的功能显而易?#8212;—改变Ҏ(gu)的参数、可见性以及返回值的cd。而进行这L改变对于调用q个Ҏ(gu)的其他方法或者代码会产生什么媄响,׃是那么显而易见了。这么也没有什么魔斏V如果代码的改变在被重构的方法内部引发了问题——变量未定义,或者类型不匚w——重构操作对q些问题q行标记。?zhn)可以选择是接受重构,E后Ҏ(gu)q些问题Q还是取消重构。如果这U重构在其他的方法中引发问题Q就直接忽略q些问题Q?zhn)必须在重构之后亲自修攏V?/p>

为澄清这一点,考虑清单16中列出的cdҎ(gu)?/p>
清单 16. MethodSigExample c?/strong>
public class MethodSigExample
{
   public int test(String s, int i)
   {
      int x = i + s.length();
      return x;
   }
}

上面q个cM?test() Ҏ(gu)被另一个类中的Ҏ(gu)调用Q如清单17所C?


清单 17. callTest Ҏ(gu)
public void callTest()
   {
     MethodSigExample eg = new MethodSigExample();
     int r = eg.test("hello", 10);
   }

在第一个类中高亮选中 test Q然后选择 Refactor > Change Method Signature。?zhn)看到如?所C的对话框?

?8. Change Method Signature 选项
Change Method Signature options

W一个选项是改变该Ҏ(gu)的可见性。在本例中,其改变?protected 或?privateQ这L二个cȝ callTest() Ҏ(gu)׃能访问这个方法了。(如果q两个类在不同的包中Q将讉KҎ(gu)设ؓ~省g会引赯L问题。) Eclipse 在进行重构的时候不会将q些问题标出Q?zhn)只有自己选择适当的倹{?

下面一个选项是改变返回值类型。如果将q回值改?float Q这不会被标记成错误Q因?test() Ҏ(gu)q回语句中的 int 会自动{换成 float 。即便如此,在第二个cȝ callTest() Ҏ(gu)中也会引起问题,因ؓ float 不能转换?int 。?zhn)需要将 test() 的返回值改?int Q或者是?callTest() 中的 r 改ؓ float ?

如果第一个参数的cd?String 变成 int Q那么也得考虑相同的问题。在重构的过E中q些问题会被标出,因ؓ它们会在被重构的Ҏ(gu)内部引v问题Q?int 不具有方?length() 。然而如果将其变?StringBuffer Q问题就不会标记出来Q因?StringBuffer 的确hҎ(gu) length() 。当然这会在 callTest() Ҏ(gu)中引起问题,因ؓ它在调用 test() 的时候还是把一?String 传递进M?

前面提到q,在重构引发了问题的情况下Q不问题是否被标出Q?zhn)都可以一个一个地修正q些问题Q以l箋下去。还有一U方法,是先行修改q些错误。如果?zhn)打算删除不再需要的参数 i Q那么可以先从要q行重构的方法中删除对它的引用。这样删除参数的q程更加顺利了?

最后一仉要解释的事情?Default Value 选项。这一选项g适用于将参数加入Ҏ(gu){֐中的情况。比方说Q如果我们加入了一个类型ؓ String 的参敎ͼ参数名ؓ n Q其~省gؓ world Q那么在 callTest() Ҏ(gu)中调?test() 的代码就变成下面的样子:

      
         public void callTest()
   {
      MethodSigExample eg = new MethodSigExample();
      int r = eg.test("hello", 10, "world");
   }

在这场有?Change Method Signature 重构的看似可怕的讨论中,我们q没有隐藏其中的问题Q但却一直没有提刎ͼq种重构其实是非常强大的工具Q它可以节约很多旉Q通常(zhn)必进行仔l的计划才能成功C用它?/p>

apple0668 2012-04-28 15:56 发表评论
]]>
JDK6中JWS自带webservice应用http://www.tkk7.com/apple0668/archive/2011/05/11/350017.htmlapple0668apple0668Wed, 11 May 2011 07:48:00 GMThttp://www.tkk7.com/apple0668/archive/2011/05/11/350017.htmlhttp://www.tkk7.com/apple0668/comments/350017.htmlhttp://www.tkk7.com/apple0668/archive/2011/05/11/350017.html#Feedback6http://www.tkk7.com/apple0668/comments/commentRss/350017.htmlhttp://www.tkk7.com/apple0668/services/trackbacks/350017.htmlwebserviceҎ(gu)之前,目中接口开发有用到Axis2、XFire、CXF{webservice框架发布通过获取相关的wsdl文g卛_实现q程通讯数据交互?br />  Axis2配合相关的IDE生成服务q发布到服务器上面相当简单和Ҏ(gu)选择其中之一的wsdl引擎生成客户端调用javac,感觉cdjar包比较庞大应用v来也比较复杂?br />  XFire是比较强大的webservice框架Q容易与web容器整合Q以及spring提供整合支持?br /> CXF是apache收购XFire后改造物,功能也相当强大?br />  使用JDK6自带的webserviceҎ(gu)后Q深感部|之单,真正的轻量Q可以你集中尽力解x务端的相兛_能设计与实现?br />  下面介绍JDK6自带的WebserviceҎ(gu)例子:

  IDEQeclipse3.6+ javaee?br /> 新徏一个java工程后,建如下类卛_单实现webserviceQ?br />
 1import javax.jws.WebService;
 2import javax.xml.ws.Endpoint;
 3
 4@WebService
 5public class HelloWorld {
 6    public String sayHello() 
 7        return "helloworld";
 8        }
 
 9        public static void main(String[] args) 
10        //发布一个WebService 
11        Endpoint.publish("http://localhost:9090/HelloWorld"new HelloWorld()); 
12        }
 
13}

14

启动mainҎ(gu)卛_发布一个webservice服务Q通过览器输?font style="background-color: #cce8cf" face="Verdana">http://localhost:9090/HelloWorld?wsdl卛_讉K?br /> 注:HelloWorld是一个普通类Q只是在cȝ前面W?行加了注?font style="background-color: #cce8cf">@WebServiceQ发布是在第11行,http://localhost:9090/HelloWorld是发布服务地址Q其中new HelloWorld()是服务类?br />      在实际项目开发中可以服务地址从硬~码中抽d理,写到配置文g或者数据库中方便维护管理,修改地址从前服务卛_?br />  


apple0668 2011-05-11 15:48 发表评论
]]>
解决QEclipse启动tomcat 讉K不了 手动启动可以讉Khttp://www.tkk7.com/apple0668/archive/2011/05/09/349875.htmlapple0668apple0668Mon, 09 May 2011 14:21:00 GMThttp://www.tkk7.com/apple0668/archive/2011/05/09/349875.htmlhttp://www.tkk7.com/apple0668/comments/349875.htmlhttp://www.tkk7.com/apple0668/archive/2011/05/09/349875.html#Feedback0http://www.tkk7.com/apple0668/comments/commentRss/349875.htmlhttp://www.tkk7.com/apple0668/services/trackbacks/349875.htmlhttp://localhost:8080讉K不到?br /> 解决办法Q在server视图上面Q双击tomcat v6.0Q打开配置H口Q在server location中默认是选中“use workspace metadata(does not modify tomcat instation)”Q改成选中W二?#8220;use tomcat installation” 服务restart卛_正常讉K?img src ="http://www.tkk7.com/apple0668/aggbug/349875.html" width = "1" height = "1" />

apple0668 2011-05-09 22:21 发表评论
]]>
IntelliJ Idea10 常用快捷?/title><link>http://www.tkk7.com/apple0668/archive/2011/05/04/349503.html</link><dc:creator>apple0668</dc:creator><author>apple0668</author><pubDate>Wed, 04 May 2011 08:09:00 GMT</pubDate><guid>http://www.tkk7.com/apple0668/archive/2011/05/04/349503.html</guid><wfw:comment>http://www.tkk7.com/apple0668/comments/349503.html</wfw:comment><comments>http://www.tkk7.com/apple0668/archive/2011/05/04/349503.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/apple0668/comments/commentRss/349503.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/apple0668/services/trackbacks/349503.html</trackback:ping><description><![CDATA[习惯了eclipse快捷键,最q用IntelliJ Idea,快捷键完全不一PC供以后参考用?br /> 快捷键如下:<br /> <br /> <font style="background-color: #cce8cf">代码提示 KEYMAP->Main menu->Code->Complete Code->Basic 讄快捷键ALT+Z 原是ctrl+I格QSPACEQ?br />                   KEYMAP->Main menu->Code->Generate 讄快捷键ALT+Insert 原是AlT+Shift+S Alt+回R 导入?<br /> 自动修正 Ctrl+N 查找c?<br /> Ctrl+Shift+N 查找文g <br /> Ctrl+Alt+L 格式化代?<br /> Ctrl+Alt+O 优化导入的类和包 <br /> Alt+Insert 生成代码(如get,setҎ(gu),构造函数等) <br /> Ctrl+E或者Alt+Shift+C 最q更改的代码 <br /> Ctrl+R 替换文本 <br /> Ctrl+F 查找文本 <br /> Ctrl+Shift+Space 自动补全代码 <br /> Ctrl+I格 代码提示 <br /> Ctrl+Alt+Space cd或接口名提示 <br /> Ctrl+P Ҏ(gu)参数提示 <br /> Ctrl+Shift+Alt+N 查找cM的方法或变量 <br /> Alt+Shift+C Ҏ(gu)最q修改的代码 <br /> Shift+F6 重构-重命?<br /> Ctrl+Shift+先上?<br /> Ctrl+X 删除?<br /> Ctrl+D 复制?<br /> Ctrl+/ ?Ctrl+Shift+/ 注释Q?/ 或?*...*/ Q?<br /> Ctrl+J 自动代码 <br /> Ctrl+E 最q打开的文?<br /> Ctrl+H 昄cȝ构图 <br /> Ctrl+Q 昄注释文档 <br /> Alt+1 快速打开或隐藏工E面?<br /> Alt+F1 查找代码所在位|?<br /> Alt+ left/right 切换代码视图 <br /> Alt+ Up/Down 在方法间快速移动定?<br /> Ctrl+Alt+ left/right q回至上ơ浏览的位置 <br /> Ctrl+Shift+Up/Down 代码向上/下移动?<br /> F2 或Shift+F2 高亮错误或警告快速定?代码标签输入完成后,按TabQ生成代码?如输?sout",再按下Tab键,可以自动生成System.out.println(); 选中文本Q按Ctrl+Shift+F7 Q高亮显C所有该文本Q按Esc高亮消失?<br /> Ctrl+W 选中代码Q连l按会有其他效果选中文本Q按Alt+F3 Q逐个往下查扄同文本,q亮显C?<br /> Ctrl+Up/Down 光标跌{到第一行或最后一行下 Ctrl+B 快速打开光标处的cLҎ(gu)</font><img src ="http://www.tkk7.com/apple0668/aggbug/349503.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/apple0668/" target="_blank">apple0668</a> 2011-05-04 16:09 <a href="http://www.tkk7.com/apple0668/archive/2011/05/04/349503.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Drools语法详解<?gt;http://www.tkk7.com/apple0668/archive/2010/01/17/309884.htmlapple0668apple0668Sun, 17 Jan 2010 13:11:00 GMThttp://www.tkk7.com/apple0668/archive/2010/01/17/309884.htmlhttp://www.tkk7.com/apple0668/comments/309884.htmlhttp://www.tkk7.com/apple0668/archive/2010/01/17/309884.html#Feedback0http://www.tkk7.com/apple0668/comments/commentRss/309884.htmlhttp://www.tkk7.com/apple0668/services/trackbacks/309884.html原文Q?font style="background-color: #cce8cf">http://www.javaeye.com/topic/190294
一个典型的DRL文gQ?
Java代码
①package com.sample   //包名Q不可以与关键字冲突  
②import com.sample.DroolsTest.Message;//本文仉要导入的c?nbsp; 
③global java.util.List myGlobalList;//全局变量  
?/定义函数?nbsp; 
function String hello(String name) {  
    return "Hello "+name+"!";  
}  
 
⑤rule "myRule"    
no-loop true  //执行一ơ后Q是否能被再ơ激z?nbsp; 
salience 100  //优先U别  
⑥when    
m : Message( status == Message.HELLO, message : message )   
⑦then      
m.setMessage( "Goodbye cruel world" );  
        m.setStatus( Message.GOODBYE );  
        update( m );  
    myGlobalList.add( "Hello World" );//使用global 变量  
    System.out.println( hello( "Bob" ) );//调用定义函数  
End 

①package com.sample   //包名Q不可以与关键字冲突
②import com.sample.DroolsTest.Message;//本文仉要导入的c?br /> ③global java.util.List myGlobalList;//全局变量
?/定义函数?br /> function String hello(String name) {
    return "Hello "+name+"!";
}

⑤rule "myRule" 
no-loop true  //执行一ơ后Q是否能被再ơ激z?br /> salience 100  //优先U别
⑥when 
m : Message( status == Message.HELLO, message : message )
⑦then   
m.setMessage( "Goodbye cruel world" );
  m.setStatus( Message.GOODBYE );
  update( m );
    myGlobalList.add( "Hello World" );//使用global 变量
    System.out.println( hello( "Bob" ) );//调用定义函数
End

 

①package com.sample
包名Q不可以与关键字冲突。一个包通过名称I间描绘Q这样很好的保持了一l规则的独立性?
②import
标记像java中的含义一栗对于Q何要用在规则中的对象Q你需要指定完整的路径和类型名。Drools从同名的java包中自动导入cR?
③global
如果多个包定义了同样名称的全局变量Q它们必M用同LcdQƈ且全部指向同一个全局倹{全部变量通常用来q回数据Q获得提供数据或服务l规则用。ؓ了用全局变量Q你必须Q?
在规则文件中声明全局变量q用它Q如Q?
global java.util.List myGlobalList;
rule "Using a global"
when
    eval( true )
then
    myGlobalList.add( "Hello World" );
end
在working memory上设|全局变量的倹{最好是在将fact插入working memory之前讄完所有全局变量Q如Q?
List list = new ArrayList();
WorkingMemory wm = rulebase.newStatefulSession();
wm.setGlobal( "myGlobalList", list );
④function
相对于正常的javac,函数是在你的规则代码中放|语a代码的方法。它们不可能做Q何超q你可以在帮助类Q在java中定义,被设|入规则的Working Memory中的c)中做到的事情。用函数的优点是可以将逻辑保存在一个地方,q且你可以在需要的时候改变函敎ͼq样做各有优~点Q。函数最大的用处是被规则的推论(thenQ部分中的行为所调用Q特别是当一个行为操作需要反复被调用Ӟ公用代码抽取出来成Z个函敎ͼ?
⑤rule 名称可以?#8220;”下取M名字?
属性列表:
属?cd 默认?功能描述
no-loop Boolean false 讄no-loop为true可以L该规则被再次ȀzR?
salience integer 0 优先U数字高的规则会比优先低的规则先执行?
agenda-group String MAIN 只有在具有焦点的agenda group中的规则才能够激发?
auto-focus Boolean false 如果该规则符合激zLӞ则该规则所在agenda-group自动获得焦点Q允许规则激发?
activation-group String N/A 在同名activation-group中的规则以互斥的方式激?
dialect String "java" or "mvel" 指定在LHS代码表达式或RHS代码块中使用的语a?
date-effective String, 包含日期/旉定义 N/A 规则只能在date-effective指定的日期和旉之后ȀzR?
date-exptires String, 包含日期/旉定义 N/A 如果当前旉在date-expires指定的时间之后,规则不能ȀzR?

duration long N/A 指出规则在指定的一D|间后Ȁ发,如果那个时候规则的ȀzL件还是处于true的情况下?
?nbsp; LHS (when) 条g元素
Z能够引用匚w的对象,使用一个模式绑定变量如‘$c’。变量的前缀使用?是可选的Q但是在复杂的规则中它会很方便用来区别变量与字段的不同?
$c : Cheese( type == "stilton", price < 10, age == "mature" )
&& 和|| U束q接W?
Cheese( type == "stilton" && price < 10, age == "mature" )
Cheese( type == "stilton" || price < 10, age == "mature" )
W一个有两个U束而第二个l有一个约束,可以通过圆括h改变求值的序?
单值约?
Matches 操作
Cheese( type matches "(Buffalo)?\S*Mozerella" )
Cheese( type not matches "(Buffulo)?\S*Mozerella" )
Contains 操作
CheeseCounter( cheeses contains "stilton" )
CheeseCounter( cheeses not contains "cheddar" )
memberof操作
CheeseCounter( cheese memberof $matureCheeses )
CheeseCounter( cheese not memberof $matureCheeses )
字符串约?
字符串约束是最单的U束格式Q将字段与指定的字符串求|数|日期Qstring或者boolean?
Cheese( quantity == 5 )
Cheese( bestBefore < "27-Oct-2007" )
Cheese( type == "stilton" )
Cheese( smelly == true )
l定变量U束
变量可以l定到Fact和它们的字段Q然后在后面的字D늺束中使用。绑定变量被UCؓ声明。有效的操作W由被约束的字段cd军_Q在那里会进行强制{换。绑定变量约束?=='操作W,因ؓ能够使用hash索引Q因此提供非常快的执行速度?
Person( likes : favouriteCheese )
Cheese( type == likes )
q回值约?
q回值约束可以用Q何有效的Java元数据类型或对象。要避免使用MDrools关键字作为声明标识。在q回值约束中使用的函数必返回静态常量(time constantQ结果。之前声明的l定可以用在表达式中?
Person( girlAge : age, sex == "F" )
Person( age == ( girlAge + 2) ), sex == 'M' )
复合值约?
复合值约束用在可能有多个允许值的时候,当前只支?in' ?not in'两个操作。这些操作用圆括号包含用逗号分开的值的列表Q它可以是变量,字符Ԍq回值或限定标识W?in' ?not in'q算式实际上被语法分析器重写成多?= and ==l成的多重约束?
Person( $cheese : favouriteCheese )
Cheese( type in ( "stilton", "cheddar", $cheese )
多重U束
多重U束允许你对一个字D通过使用'&&' 或?||'U束q接W进行多个约束条件的判断。允怋用圆括号分组Q它会让q种U束看v来更自然?
Person( age ( (> 30 && < 40) || (> 20 && < 25) ) )
Person( age > 30 && < 40 || location == "london" )
内联的EvalU束
evalU束可以使用M有效的语a表达式,只要它最l能被求gؓboolean元数据类型。表辑ּ必须是静态常量(time constantQ。Q何在当前模式之前定义的变量都可以使用Q自动代入(autovivificationQ机制用来自动徏立字D늻定变量。当构徏器发现标识不是当前定义的变量名是Q它?yu)尝试将它作为对象的字段来访问,q种情况下,构徏器自动在inline-eval中徏立该字段的同名变量?
Person( girlAge : age, sex = "F" )
Person( eval( girlAge == boyAge + 2 ), sex = 'M' )

⑦RHS (then) 执行操作
q部分应当包含一pd需要执行的操作。规则的RHS部分应该保持短的Q这保持它是声明性和可读性的。如果你发现你需要在RHS中用命令式或and/or条g代码Q那你可能需要将规则拆分为多个规则。RHS的主要目的是插入Q删除修改working memory数据?
"update(object, handle);" 告诉引擎对象已l改变(已经被绑定到LHS中的那一个)Qƈ且规则需要重新检查?
"insert(new Something());" 在working memory中放|一个你新徏的对象?
"insertLogical(new Something());" 与insertcMQ但是当没有更多的fact支持当前Ȁ发规则的真值状态时Q对象自动删除?
"retract(handle);" removes an object from working memory.
?Query
查询中仅仅包含规则LHS部分的结构(不用指定when或thenQ。它提供了查询working memory 中符合约束条件的对象的一个简单办法?
query "people over the age of 30"
    person : Person( age > 30 )
end
通过在返回的查询l果(QueryResults)上进行标准的for循环遍历Q每一行将q回一个QueryResultQ该对象可以用来存取l元中的每一个Column。这些Column可以通过声明的名U或索引位置存取?
QueryResults results = workingMemory.getQueryResults( "people over the age of 30" );
for ( Iterator it = results.iterator; it.hasNext(); ) {
    QueryResult result = ( QueryResult ) it.next();
    Person person = ( Person ) result.get( "person" );
    }

 



apple0668 2010-01-17 21:11 发表评论
]]>
eclipse3.4安装drools插g手记http://www.tkk7.com/apple0668/archive/2010/01/17/309883.htmlapple0668apple0668Sun, 17 Jan 2010 13:08:00 GMThttp://www.tkk7.com/apple0668/archive/2010/01/17/309883.htmlhttp://www.tkk7.com/apple0668/comments/309883.htmlhttp://www.tkk7.com/apple0668/archive/2010/01/17/309883.html#Feedback2http://www.tkk7.com/apple0668/comments/commentRss/309883.htmlhttp://www.tkk7.com/apple0668/services/trackbacks/309883.html 下蝲drools eclipse插gQ地址为:http://www.jboss.org/drools/downloads.html
解压用links方式安装插gQ如?font style="background-color: #cce8cf">features目录?font style="background-color: #cce8cf">plugins目录上层没有eclipse文g夹,pZ个?br />
在Eclipse目录下面新徏一个links文g夹,里面Z个XXX.linkQ内容ؓQpath=F://plugins/drools

启动EclipseQ在window----prefernces那里如果看不到又droolsQ就说明插g安装不成功?br />
Eclipse3.4安装drools插g遇到识别不了插gQ解x案如下:

F:\eclipse\configuration\org.eclipse.equinox.simpleconfigurator下面bundles.info最后加上以下几句:

org.guvnor.tools,5.0.1,file:plugins\org.guvnor.tools_5.0.1.jar,4,false
org.eclipse.webdav,3.0.101,file:plugins\org.eclipse.webdav_3.0.101.jar,4,false
org.drools.eclipse,5.0.1,file:plugins\org.drools.eclipse_5.0.1.jar,4,false
org.drools.eclipse.task,5.0.1,file:plugins\org.drools.eclipse.task_5.0.1.jar,4,false

保存卛_?br />
再次启动Eclipse可以成功安装插Ӟwindow----prefernces---drools插gQ配|drools的依赖包环境Q这些很单,省略?br />
新徏一个drools工程Q就会看C个附带的helloworld的例子,执行java文g卛_执行试?br />
Sample.drl

package com.sample
 
import com.sample.DroolsTest.Message;
 
rule "Hello World"
    when
        m : Message( status == Message.HELLO, myMessage : message )
    then
        System.out.println( myMessage ); 
        m.setMessage( "Goodbye cruel world" );
        m.setStatus( Message.GOODBYE );
        update( m );
end

rule "GoodBye"
    when
        Message( status == Message.GOODBYE, myMessage : message )
    then
        System.out.println( myMessage );
end


DroolsTest.java

 1package com.sample;
 2
 3import org.drools.KnowledgeBase;
 4import org.drools.KnowledgeBaseFactory;
 5import org.drools.builder.KnowledgeBuilder;
 6import org.drools.builder.KnowledgeBuilderError;
 7import org.drools.builder.KnowledgeBuilderErrors;
 8import org.drools.builder.KnowledgeBuilderFactory;
 9import org.drools.builder.ResourceType;
10import org.drools.io.ResourceFactory;
11import org.drools.logger.KnowledgeRuntimeLogger;
12import org.drools.logger.KnowledgeRuntimeLoggerFactory;
13import org.drools.runtime.StatefulKnowledgeSession;
14
15/**
16 * This is a sample class to launch a rule.
17 */

18public class DroolsTest {
19
20    public static final void main(String[] args) {
21        try {
22            // load up the knowledge base
23            KnowledgeBase kbase = readKnowledgeBase();
24            StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
25            KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
26            // go !
27            Message message = new Message();
28            message.setMessage("Hello World");
29            message.setStatus(Message.HELLO);
30            ksession.insert(message);
31            ksession.fireAllRules();
32            logger.close();
33        }
 catch (Throwable t) {
34            t.printStackTrace();
35        }

36    }

37
38    private static KnowledgeBase readKnowledgeBase() throws Exception {
39        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
40        kbuilder.add(ResourceFactory.newClassPathResource("Sample.drl"), ResourceType.DRL);
41        KnowledgeBuilderErrors errors = kbuilder.getErrors();
42        if (errors.size() > 0{
43            for (KnowledgeBuilderError error: errors) {
44                System.err.println(error);
45            }

46            throw new IllegalArgumentException("Could not parse knowledge.");
47        }

48        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
49        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
50        return kbase;
51    }

52
53    public static class Message {
54        
55        public static final int HELLO = 0;
56        public static final int GOODBYE = 1;
57
58        private String message;
59
60        private int status;
61
62        public String getMessage() {
63            return this.message;
64        }

65
66        public void setMessage(String message) {
67            this.message = message;
68        }

69
70        public int getStatus() {
71            return this.status;
72        }

73
74        public void setStatus(int status) {
75            this.status = status;
76        }

77        
78    }

79
80}

输出Q?br />
Hello World
Goodbye cruel world



apple0668 2010-01-17 21:08 发表评论
]]>
Java日期旉q算http://www.tkk7.com/apple0668/archive/2009/03/19/260902.htmlapple0668apple0668Thu, 19 Mar 2009 13:56:00 GMThttp://www.tkk7.com/apple0668/archive/2009/03/19/260902.htmlhttp://www.tkk7.com/apple0668/comments/260902.htmlhttp://www.tkk7.com/apple0668/archive/2009/03/19/260902.html#Feedback0http://www.tkk7.com/apple0668/comments/commentRss/260902.htmlhttp://www.tkk7.com/apple0668/services/trackbacks/260902.html今天处理一个Java日期旉q算问题Q?br /> 试q几U方法,觉得q是如下Ҏ(gu)处理比较灉|Q代码如下:

 

 1package org.mmc.date.cal;
 2
 3import java.util.Date;
 4import java.util.Calendar;
 5import java.util.GregorianCalendar;
 6import java.text.SimpleDateFormat;
 7public class DateCal {
 8    Date date = new Date();
 9    GregorianCalendar gc = new GregorianCalendar();
10    SimpleDateFormat  sf = new SimpleDateFormat("yyyy-MM-dd HH:MM:ss");
11    /**
12     * 
13     * gc.add(1,1)q䆾?
14     * gc.add(2,1)月䆾?
15     * gc.add(3,1)周加1
16     * gc.add(5,1)天加1
17     * 如果?1表示是减
18     */

19    public String getDateCal(int d,int beforeMonth)
20    {
21        gc.setTime(date);
22        gc.add(d,beforeMonth);
23        gc.set(gc.get(Calendar.YEAR),gc.get(Calendar.MONTH),gc.get(Calendar.DATE));
24        return sf.format(gc.getTime());
25    }

26    public String getCurrentDate()
27    {
28        return sf.format(date);
29    }

30    public static  void  main(String[] args)
31    {
32        DateCal ud= new DateCal();
33        System.out.println("当前旉  Q?/span>"+ud.getCurrentDate());
34        System.out.println("前一q?nbsp;   Q?/span>"+ud.getDateCal(1-1));
35        System.out.println("前一个月  Q?/span>"+ud.getDateCal(2,-1));
36        System.out.println("前一个星期:"+ud.getDateCal(3-1));
37        System.out.println("前一?nbsp;   Q?/span>"+ud.getDateCal(5-1));
38    }

39
40}

41 
42


输出l果Q?br />
当前旉  Q?009-03-19 21:03:48
前一q?nbsp;   Q?008-03-19 21:03:48
前一个月  Q?009-02-19 21:02:48
前一个星期:2009-03-12 21:03:48
前一?nbsp;   Q?009-03-18 21:03:48
分析Q?br /> 深入GregorianCalendar中的addҎ(gu)源码Q代码比较长想研I的自己看源代码?br />


 



apple0668 2009-03-19 21:56 发表评论
]]>
java中用功能强(zhn)的正则表达?/title><link>http://www.tkk7.com/apple0668/archive/2008/12/06/244820.html</link><dc:creator>apple0668</dc:creator><author>apple0668</author><pubDate>Sat, 06 Dec 2008 15:42:00 GMT</pubDate><guid>http://www.tkk7.com/apple0668/archive/2008/12/06/244820.html</guid><wfw:comment>http://www.tkk7.com/apple0668/comments/244820.html</wfw:comment><comments>http://www.tkk7.com/apple0668/archive/2008/12/06/244820.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/apple0668/comments/commentRss/244820.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/apple0668/services/trackbacks/244820.html</trackback:ping><description><![CDATA[     摘要:         最q深入看struts2的validation校验框架Q看到底层的很多的实现都用到正则表达式来实现。其中用得比较多的是两个c,一个是java.util.regex.Matcher和java.util.regex.Pattern       &...  <a href='http://www.tkk7.com/apple0668/archive/2008/12/06/244820.html'>阅读全文</a><img src ="http://www.tkk7.com/apple0668/aggbug/244820.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/apple0668/" target="_blank">apple0668</a> 2008-12-06 23:42 <a href="http://www.tkk7.com/apple0668/archive/2008/12/06/244820.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://139699.com" target="_blank">޳a߹ۿ</a>| <a href="http://sitefmns.com" target="_blank">һձþþ</a>| <a href="http://dgyinhezy.com" target="_blank">߹ۿѹۿַ</a>| <a href="http://8mav938.com" target="_blank">츾ɫ͵</a>| <a href="http://3334598.com" target="_blank">ִӲëƬ</a>| <a href="http://0769wwt.com" target="_blank">˵ĺÿѹۿƵ </a>| <a href="http://jte-sh.com" target="_blank">޾ƷպAV</a>| <a href="http://yiqigxfc.com" target="_blank">Ů˾޸</a>| <a href="http://88109a.com" target="_blank">պëƬѿ</a>| <a href="http://linanhotel.com" target="_blank">þ99ȾƷѹۿţţ</a>| <a href="http://zgjzysfc.com" target="_blank">ɫAV߹ۿ</a>| <a href="http://sdnuoyuan.com" target="_blank">޼Ƶվ</a>| <a href="http://hidiaoyan.com" target="_blank">þþþŷղAV </a>| <a href="http://gsonlinet.com" target="_blank">þþƷվ</a>| <a href="http://zgnyxx.com" target="_blank">ù͵v͵v</a>| <a href="http://m8va.com" target="_blank">Ʒպһ </a>| <a href="http://8k91.com" target="_blank">˾Ʒֱ</a>| <a href="http://by4471.com" target="_blank">Ļ벻Ƶ</a>| <a href="http://www759696b.com" target="_blank">þþþþëƬѲ</a>| <a href="http://sczxzt.com" target="_blank">99Ƶ߹ۿ</a>| <a href="http://0515zs.com" target="_blank">AAAAAٸ߳Ƭѿ</a>| <a href="http://www-188588.com" target="_blank">˾ҹƵ</a>| <a href="http://liexion.com" target="_blank">һػaaaƬѿ</a>| <a href="http://gstywy.com" target="_blank">gayˬˬƵ</a>| <a href="http://tccqdy.com" target="_blank">޵һƵ߹ۿ</a>| <a href="http://haichuanwangluo.com" target="_blank">Ƭ߹ۿѹۿȫй</a>| <a href="http://baiyifuwu.com" target="_blank">ۺϾþþƷ</a>| <a href="http://bqjonline.com" target="_blank">޹AVһ</a>| <a href="http://xtolm.com" target="_blank">ɫ͵͵ɫݺ99</a>| <a href="http://boyipark.com" target="_blank">ɫaAV</a>| <a href="http://789xxoo.com" target="_blank">޾Ʒ</a>| <a href="http://b2bautoparts.com" target="_blank">91ƵƷȫѹۿ</a>| <a href="http://senimei9.com" target="_blank">Ƶ߹ۿ</a>| <a href="http://ganbadei.com" target="_blank">ĻѸ</a>| <a href="http://bjqhkf.com" target="_blank">СƵ߹ۿ</a>| <a href="http://1408600.com" target="_blank">þAV뾫Ʒ</a>| <a href="http://www2019rz.com" target="_blank">˳߹ۿ</a>| <a href="http://fkg675.com" target="_blank">Ļ߲</a>| <a href="http://huakangweicai.com" target="_blank">ɫ㽶</a>| <a href="http://180xiu.com" target="_blank">һƵ</a>| <a href="http://kssijia.com" 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>