Friday, May 24, 2013

Strategy Pattern

Strategy Pattern

Strategy Pattern là gì?
Đây là một behavioral pattern, định nghĩa một tập những thuật toán mà có thể chuyển đổi lẫn nhau để thực hiện một tác vụ cụ thể nào đó.


Biểu đồ sau đây cho ta thấy được cách client gọi Strategy pattern và cách nó hoạt động như thế nào:


Tại sao chúng ta cần Strategy Pattern?
Trong phát triển phần mềm, đôi lúc ta có gặp một số tình huống mà ở đó một số class nó chỉ khác nhau ở thuật toán để thực hiện công việc. Thay vì phải tạo ra nhiều classes gần như là giống nhau thì ta sẽ chỉ tách những phần thuật toán khác nhau ra thành những class khác. Sau đó việc chọn lựa sử dụng thuật toán nào đó sẽ được quyết định sau.

Cách thức để implement Strategy Pattern?
Lấy ví dụ một tool nén file
//Strategy Interface
public interface CompressionStrategy {
       public void compressFiles(ArrayList<File> files);
}

public class ZipCompressionStrategy implements CompressionStrategy {

       public void compressFiles(ArrayList<File> files) {
              // using ZIP approach
       }

}

public class RarCompressionStrategy implements CompressionStrategy {

       public void compressFiles(ArrayList<File> files) {
              // using RAR approach
       }

}

public class CompressionContext {
       private CompressionStrategy strategy;

       // this can be set at runtime by the application preferences
       public void setCompressionStrategy(CompressionStrategy strategy) {
              this.strategy = strategy;
       }

       // use the strategy
       public void createArchive(ArrayList<File> files) {
              strategy.compressFiles(files);
       }

}

public class Client {

       public static void main(String[] args)
   {
      CompressionContext ctx = new CompressionContext();
     //we could assume context is already set by preferences
      ctx.setCompressionStrategy(new ZipCompressionStrategy());    
     //get a list of files
    ...
     ctx.createArchive(fileList);   

   }
}


Một ví dụ nữa về Robot:
Chúng ta có nhiều loại Robot nhưng về cơ bản nó cũng chỉ là Robot. Điều khác nhau giữa những Robot này đó là nó có những hành động khác nhau tùy từng loại.

public interface IBehaviour {
       public int moveCommand();
}

public class AgressiveBehaviour implements IBehaviour {
       public int moveCommand() {
              System.out
                           .println("\tAgressive Behaviour: if find another robot attack it");
              return 1;
       }
}

public class DefensiveBehaviour implements IBehaviour {
       public int moveCommand() {
              System.out
                           .println("\tDefensive Behaviour: if find another robot run from it");
              return -1;
       }
}

public class NormalBehaviour implements IBehaviour {
       public int moveCommand() {
              System.out
                           .println("\tNormal Behaviour: if find another robot ignore it");
              return 0;
       }
}

public class Robot {
       IBehaviour behaviour;
       String name;

       public Robot(String name) {
              this.name = name;
       }

       public void setBehaviour(IBehaviour behaviour) {
              this.behaviour = behaviour;
       }

       public IBehaviour getBehaviour() {
              return behaviour;
       }

       public void move() {
              System.out.println(this.name + ": Based on current position"
                           + "the behaviour object decide the next move:");
              int command = behaviour.moveCommand();
              // ... send the command to mechanisms
              System.out.println("\tThe result returned by behaviour object "
                           + "is sent to the movement mechanisms " + " for the robot '"
                           + this.name + "'");
       }

       public String getName() {
              return name;
       }

       public void setName(String name) {
              this.name = name;
       }
}

public class Main {

       public static void main(String[] args) {

              Robot r1 = new Robot("Big Robot");
              Robot r2 = new Robot("George v.2.1");
              Robot r3 = new Robot("R2");

              r1.setBehaviour(new AgressiveBehaviour());
              r2.setBehaviour(new DefensiveBehaviour());
              r3.setBehaviour(new NormalBehaviour());

              r1.move();
              r2.move();
              r3.move();

              System.out.println("\r\nNew behaviours: "
                           + "\r\n\t'Big Robot' gets really scared"
                           + "\r\n\t, 'George v.2.1' becomes really mad because"
                           + "it's always attacked by other robots"
                           + "\r\n\t and R2 keeps its calm\r\n");

              r1.setBehaviour(new DefensiveBehaviour());
              r2.setBehaviour(new AgressiveBehaviour());

              r1.move();
              r2.move();
              r3.move();
       }

}

Tổng kết
Chúng ta sẽ áp dụng design pattern này khi có nhu cầu thay đổi thuật toán lúc run-time
Strategy pattern cung cấp cho ta một cách để tạo một họ những thuật toán như những Object và sau đó có thể thay đổi lẫn nhau giữa chúng lúc run-time.



0 comments:

Post a Comment