模式总结——模板方法

在这么多有用的模式中,个人觉得模板方法是最难以理解的,而且不太好用,说实在的,是不太好设计,不知道何时要应用这个模式,其实每个模式都要理解很重要的一点:出发点是什么?换句话说,是什么因素,导致我需要这个模式。


public class Action1 {
    
    
public void open(){
        
//打开数据库
    }

    
public void close(){
        
//关闭数据库
    }

    
    
public void action(){
        open();
        
//执行一些程序
        close();
    }

}


public class Action2 {
    
    
public void open(){
        
//打开数据库
    }

    
public void close(){
        
//关闭数据库
    }

    
    
public void action(){
        open();
        
//执行另外一些程序
        close();
    }

}

上2个类的open close方法是一摸一样的,唯一不同的就在于action方法,当我们再需要这样一个类的时候,可以复制open close方法,其实也挺方便的,但恐怖之处在于,万一open或者close方法有点小BUG,那岂不是每个类都要去修改?这样就带来了很大的风险,于是我们的出发点在于,把open close 方法提取出来,我们来建立一个类


public abstract class AbstractAction {

    
public void open(){
        
//打开数据库
    }

    
public void close(){
        
//关闭数据库
    }

    
}


public class Action1 extends AbstractAction {
    

    
public void action(){
        open();
        
//执行一些程序
        close();
    }

}


public class Action2 extends AbstractAction {
    

    
public void action(){
        open();
        
//执行另外一些程序
        close();
    }

}

让Action1 Action2 这2个类继承它,好了,现在是不是已经把open 和 close都提取出来了,action1 和 action2调用的都是同一套方法了,接着的精华在于,把 action也提取到抽象类上


public abstract class AbstractAction {

    
public abstract void action();
    
    
public void open(){
        
//打开数据库
    }

    
public void close(){
        
//关闭数据库
    }

    
}

这样设计好之后, AbstractAction action = new  Action1();          action.action()    接口就统一起来了

调用的流程其实是比较复杂的,AbstractAction  的action方法往Action1里面找,action1里面的action方法里面的open close方法再往AbstractAction 里找,有一个调用来调用去的过程,优美往往伴随着复杂,就是这个道理

总结下,我们设计的出发点,其实是从子类出发的,这样只是便于理解,其实更多的时候在于从父类出发考虑,父类把一些通用的方法都定义好,然后交代清楚要让子类做什么,也就是定义abstract方法。这样的设计非常像刻模子,子类继承父类就是一个复制品,但还不能拿来用,需要加工一下,也就是要实现abstract方法。

标签:, , ,


一步一步学Repast 第二章(把界面显示出来2)

上一章,我们用了TextDisplay和Value2DDisplay来显示界面,Value2DDisplay用 Discrete2DSpace和ColorMap配合来进行显示。现在我们讨论下 Object2DDisplay,看看它的构造函数:uchicago.src.sim.gui.Object2DDisplay.Object2DDisplay(Discrete2DSpace)
可以看出,没有了ColorMap,那么它是如何进行绘制的呢?按照我们的推论,肯定是Discrete2DSpace里的Object实现了某种绘制的接口。比如  :
new Object2DGrid(50,50).putObjectAt(20,20,myObject)    这里的myObject一定已经实现了某种绘制功能。 阅读全文 »

标签:, , , , , , , , ,


一步一步学Repast 第二章(把界面显示出来)

这一章我们来讨论下CarryDropSpace,它主要负责界面上的工作。来看一下它的代码:

  1. // CarryDropSpace.java
  2. package demo;
  3.  
  4. import uchicago.src.sim.space.Object2DGrid; //这是space包中最常见的类,它是以一种非连续的格子来存放object,以x轴和y轴来标识。
  5.  
  6.   
  7.  
  8.  
  9. public class CarryDropSpace ...{
  10. private Object2DGrid moneySpace;
  11.  
  12.   public CarryDropSpace(int xSize, int ySize)...{
  13.     moneySpace = new Object2DGrid(xSize, ySize);
  14.  
  15.     for(int i = 0; i < xSize; i++)...{
  16.       for(int j = 0; j < ySize; j++)...{
  17.         moneySpace.putObjectAt(i,j,new Integer(0))//把所有的格子都放满 Integer(0) 这个对象。
  18.       }
  19.     }
  20.   }
  21.  
  22.   public void spreadMoney(int money)...{
  23.     // Randomly place money in moneySpace
  24.     for(int i = 0; i < money; i++)...{
  25.  
  26.       // Choose coordinates
  27.       int x = (int)(Math.random()*(moneySpace.getSizeX()));
  28.       int y = (int)(Math.random()*(moneySpace.getSizeY()));
  29.  
  30.       // Get the value of the object at those coordinates
  31.       int currentValue = getMoneyAt(x, y);
  32.       // Replace the Integer object with another one with the new value
  33.       moneySpace.putObjectAt(x,y,new Integer(currentValue + 1));   //随机改变money个格子里的对象为 Integer(1)
  34.      }
  35.   }
  36.  
  37.   public int getMoneyAt(int x, int y)...{
  38.     int i;
  39.     if(moneySpace.getObjectAt(x,y)!= null)...{
  40.       i = ((Integer)moneySpace.getObjectAt(x,y)).intValue();
  41.     }
  42.     else...{
  43.       i = 0;
  44.     }
  45.     return i;
  46.   }
  47.  
  48.   public Object2DGrid getCurrentMoneySpace()...{
  49.     return moneySpace;
  50.   }
  51.  
  52. }

阅读全文 »

标签:, , , , , , , , ,