Total Pageviews

2011/08/31

Example of the Strategy Design Pattern

Summary


The Strategy Design Pattern consists of a number of related algorithms encapsulated in a driver class often named Context. A user or a client program typically selects the algorithm they want to use, although the Context class may also select the algorithm automatically.


The intent of the Strategy Pattern is to make the algorithms easily interchangeable, and provide a means to choose the appropriate algorithm at a particular time.


Here is a brief summary of the Strategy Design Pattern:

  • Algorithms (strategies) are chosen at runtime.
  • A Strategy is dynamically selected by a client (a user or consuming program), or by the Context.
  • Your driver/controller class is typically named Context, though there is no requirement for this.
  • The Context class is aware of a variety of different algorithms, and each algorithm is considered a Strategy, and the name Strategy is often used as part of each class name, although again, this is only convention, and not a requirement.
  • The Context class is responsible for handling the data during the interaction with the client.

Example of the Strategy Design Pattern


NIG687提供一個介面讓使用者分別去搜尋異動記錄檔,包括

  • NIGU001 - 違章案件管制異動檔
  • NIGU005 - 案件紀錄異動檔
  • NIGU008 - 審理人員狀況維護檔(二)
  • NIGU014 - 未分配異動檔
  • NIGU015 - 已分配異動檔
  • NIGU020 - 列印參數維護檔
  • NIGU021 - 裁處書預設內容異動檔
  • NIGU036 - 違章機關代碼維護檔
  • NIGU037 - 適用法條代碼異動檔
  • NIGU038 - 違章事實代碼異動檔
  • NIGU039 - 違章作業代號異動檔
  • NIGU040 - 免議(罰)、撤銷、更裁原因代碼異動檔
  • NIGU042 - 附案證據代碼異動檔
  • NIGU050 - 違章月統計異動檔
  • NIGU081 - 法務科科室稅目對照維護檔
  • NIGU086 - 記帳士法徵銷管制異動檔
此function會有16個strategies


Class Diagram


Strategy interface: The classes that implement a concrete strategy should implement this interface.


在strategy interface中,定義其共同會使用到的algorithm or strategy
1:  package gov.fdc.nig.query.service.nig687;  
2:  import gov.fdc.common.table.Paging;  
3:  import gov.fdc.nig.query.service.params.NIG687Params;  
4:  /**  
5:  * @author albert  
6:  *  
7:  */  
8:  public interface Strategy {  
9:       Paging doQuery(NIG687Params params, final int rowsPerPage, final String sortDir);  
10:  }  





Context class: Configured with a ConcreteStrategy object and maintains a reference to a Strategy object.


負責建立與strategy class之間的關係,呼叫其相對應的strategy class method,以及接收client傳送過來的參數
1:  package gov.fdc.nig.query.service.nig687;  
2:  import gov.fdc.common.table.Paging;  
3:  import gov.fdc.nig.query.service.params.NIG687Params;  
4:  /**  
5:  * @author albert  
6:  *   
7:  */  
8:  public class Context {  
9:       private Strategy strategy;  
10:       public void setNIGU001Strategy() {  
11:            this.strategy = new NIGU001Strategy();  
12:       }  
13:       public void setNIGU005Strategy() {  
14:            this.strategy = new NIGU005Strategy();  
15:       }  
16:       public void setNIGU008Strategy() {  
17:            this.strategy = new NIGU008Strategy();  
18:       }  
19:       public void setNIGU014Strategy() {  
20:            this.strategy = new NIGU014Strategy();  
21:       }  
22:       public void setNIGU015Strategy() {  
23:            this.strategy = new NIGU015Strategy();  
24:       }  
25:       public void setNIGU020Strategy() {  
26:            this.strategy = new NIGU020Strategy();  
27:       }  
28:       public void setNIGU021Strategy() {  
29:            this.strategy = new NIGU021Strategy();  
30:       }  
31:       public void setNIGU036Strategy() {  
32:            this.strategy = new NIGU036Strategy();  
33:       }  
34:       public void setNIGU037Strategy() {  
35:            this.strategy = new NIGU037Strategy();  
36:       }  
37:       public void setNIGU038Strategy() {  
38:            this.strategy = new NIGU038Strategy();  
39:       }  
40:       public void setNIGU039Strategy() {  
41:            this.strategy = new NIGU039Strategy();  
42:       }  
43:       public void setNIGU040Strategy() {  
44:            this.strategy = new NIGU040Strategy();  
45:       }  
46:       public void setNIGU042Strategy() {  
47:            this.strategy = new NIGU042Strategy();  
48:       }  
49:       public void setNIGU050Strategy() {  
50:            this.strategy = new NIGU050Strategy();  
51:       }  
52:       public void setNIGU081Strategy() {  
53:            this.strategy = new NIGU081Strategy();  
54:       }  
55:       public void setNIGU086Strategy() {  
56:            this.strategy = new NIGU086Strategy();  
57:       }  
58:       public Paging executeStrategy(NIG687Params params,final int rowsPerPage, final String sortDir) {  
59:            return strategy.doQuery(params, rowsPerPage, sortDir);  
60:       }  
61:  }  





Concrete Strategy class implementations shown below here.


定義Strategy class的細部運作細節


NIGU001 Strategy class
1:  package gov.fdc.nig.query.service.nig687;  
2:  import gov.fdc.common.dao.wherecon.SimpleCriteria;  
3:  import gov.fdc.common.table.Paging;  
4:  import gov.fdc.nig.dao.Nigu001Dao;  
5:  import gov.fdc.nig.domain.Nigu001;  
6:  import gov.fdc.nig.domain.Nigu001PK;  
7:  import gov.fdc.nig.query.service.params.NIG687Params;  
8:  import org.apache.commons.lang.StringUtils;  
9:  import org.springframework.beans.factory.annotation.Autowired;  
10:  /**  
11:  * @author albert  
12:  *  
13:  */  
14:  public class NIGU001Strategy implements Strategy {  
15:       @Autowired  
16:       private transient Nigu001Dao nigu001Dao;  
17:       /* (non-Javadoc)  
18:       * @see gov.fdc.nig.query.service.nig687.Strategy#doQuery(gov.fdc.nig.query.service.params.NIG687Params)  
19:       */  
20:       @Override  
21:       public Paging doQuery(NIG687Params params, final int rowsPerPage, final String sortDir) {  
22:            final SimpleCriteria whereCondition = new SimpleCriteria();  
23:            Nigu001PK primaryKey = (Nigu001PK)params.getPrimaryKey();  
24:            if(StringUtils.isNotEmpty(primaryKey.getDlvUnit()) &&  
25:               StringUtils.isNotEmpty(primaryKey.getTaxCd()) &&  
26:              StringUtils.isNotEmpty(primaryKey.getDlvYr()) &&  
27:              StringUtils.isNotEmpty(primaryKey.getFlgTp()) &&  
28:              StringUtils.isNotEmpty(primaryKey.getSerialNo())){  
29:                 whereCondition.eq("id.dlvUnit", primaryKey.getDlvUnit());  
30:                 whereCondition.eq("id.taxCd", primaryKey.getTaxCd());  
31:                 whereCondition.eq("id.dlvYr", primaryKey.getDlvYr());  
32:                 whereCondition.eq("id.flgTp", primaryKey.getFlgTp());  
33:                 whereCondition.eq("id.serialNo", primaryKey.getSerialNo());  
34:            }  
35:            // 取得排序方向, 如果有的話代表是要排序  
36:            if (sortDir != null){  
37:                 whereCondition.orderBy("id", sortDir.equals("asc"));  
38:            }else{  
39:                 whereCondition.orderBy("id", true); // 預設照seqNo由小到大排  
40:            }  
41:            // 執行查詢  
42:            return new Paging(new Nigu001(), null, whereCondition, rowsPerPage, 100, nigu001Dao);  
43:       }  
44:  }  





NIGU005 Strategy Class
1:  package gov.fdc.nig.query.service.nig687;  
2:  import gov.fdc.common.dao.wherecon.SimpleCriteria;  
3:  import gov.fdc.common.table.Paging;  
4:  import gov.fdc.nig.dao.Nigu005Dao;  
5:  import gov.fdc.nig.domain.Nigu005;  
6:  import gov.fdc.nig.domain.Nigu005PK;  
7:  import gov.fdc.nig.query.service.params.NIG687Params;  
8:  import org.apache.commons.lang.StringUtils;  
9:  import org.springframework.beans.factory.annotation.Autowired;  
10:  /**  
11:  * @author albert  
12:  *   
13:  */  
14:  public class NIGU005Strategy implements Strategy {  
15:       @Autowired  
16:       private transient Nigu005Dao nigu005Dao;  
17:       /*  
18:       * (non-Javadoc)  
19:       *   
20:       * @see  
21:       * gov.fdc.nig.query.service.nig687.Strategy#doQuery(gov.fdc.nig.query.service  
22:       * .params.NIG687Params, int, java.lang.String)  
23:       */  
24:       @Override  
25:       public Paging doQuery(NIG687Params params, int rowsPerPage, String sortDir) {  
26:            final SimpleCriteria whereCondition = new SimpleCriteria();  
27:            Nigu005PK primaryKey = (Nigu005PK) params.getPrimaryKey();  
28:            if (StringUtils.isNotEmpty(primaryKey.getDlvUnit())     &&   
29:              StringUtils.isNotEmpty(primaryKey.getTaxCd()) &&   
30:                 StringUtils.isNotEmpty(primaryKey.getDlvYr()) &&   
31:                 StringUtils.isNotEmpty(primaryKey.getFlgTp()) &&   
32:                 StringUtils.isNotEmpty(primaryKey.getSerialNo())) {  
33:                   whereCondition.eq("id.dlvUnit", primaryKey.getDlvUnit());  
34:                  whereCondition.eq("id.taxCd", primaryKey.getTaxCd());  
35:                  whereCondition.eq("id.dlvYr", primaryKey.getDlvYr());  
36:                  whereCondition.eq("id.flgTp", primaryKey.getFlgTp());  
37:                  whereCondition.eq("id.serialNo", primaryKey.getSerialNo());  
38:            }  
39:            // 取得排序方向, 如果有的話代表是要排序  
40:            if (sortDir != null) {  
41:                 whereCondition.orderBy("id", sortDir.equals("asc"));  
42:            } else {  
43:                 whereCondition.orderBy("id", true); // 預設照seqNo由小到大排  
44:            }  
45:            // 執行查詢  
46:            return new Paging(new Nigu005(), null, whereCondition, rowsPerPage, 100, nigu005Dao);  
47:       }  
48:  }  





this is our "driver" method to demonstrate our Java Strategy Design Pattern example
1:  public static void main(String[] args){  
2:       Context context;  
3:       //搜尋NIGU001 table的資料  
4:       context = new Context();  
5:       context.setNIGU001Strategy();  
6:       context.executeStrategy(params, rowsPerPage, sortDir);  
7:       //搜尋NIGU005 table的資料  
8:       context = new Context();  
9:       context.setNIGU005Strategy();  
10:      context.executeStrategy(params, rowsPerPage, sortDir);  
11:  }  


No comments: