策略模式



策略模式

  • 策略模式:也叫作政策模式,定義一組算法,將每個算法都封裝起來,並且使他們之間可以互換
  • 策略模式的使用就是面向對象的繼承和多態機制,其通用類圖如下:

 

 

    • Context封裝角色,也叫作上下文角色,屏蔽高層模塊對策略、算法的直接訪問,封裝可能的變化。
    • Istrategy抽象策略角色,策略算法家族的抽象,通常為接口定義每個算法必須具有的方法和屬性。
    • ConcreteStrategy具體策略角色,實現抽象策略中的操作該類含有具體的算法。

通用類圖的源碼如下:

    • public interface IStrategy {
          //定義具體策略必須具有的方法
          public void doSomething();
      }
      
      public class ConcreteStrategy1 implements IStrategy{
          public void doSomething(){
              System.out.println("this is a concreteStrategy");
          }
      }
      
      public class ConcreteStrategy2 implements IStrategy{
      
          @Override
          public void doSomething() {
              // TODO Auto-generated method stub
              System.out.println("This is concreteStrategy2");
          }
      }
      
      public class Context {
          private IStrategy strategy = null;
          public Context(IStrategy strategy){
              this.strategy = strategy;
          }
          public void doSomething(){
              this.strategy.doSomething();
          }
      }
      
      public class Client {
      
          /**
           * @param args
           */
          public static void main(String[] args) {
              // TODO Auto-generated method stub
              Context text = new Context(new ConcreteStrategy2());
              text.doSomething();
              text = new Context(new ConcreteStrategy1());
              text.doSomething();
          }
      }
策略模式的優缺點
  • 策略模式的優點
    • 算法可以自由的切換,通過實現抽象策略,通過封裝角色對其封裝,保證對外提供“可自由切換”的策略。
    • 避免使用多重條件判斷,如果有多重策略,那么每個策略只需實現自己的方法,至於采用何種策略,可以通過其他模塊決定。
    • 擴展性良好,可以在現有的系統中任意的加入新的策略,只需繼承IStrategy接口,符合OCP原則。
  • 策略模式的缺點
    • 策略類數量增多,每個策略都是一個類,復用的可能性很小,類數量增多
    • 所有的策略都需要對外暴露,上層模塊必須知道有哪些策略,然后才能知道采用哪種策略,可以通過使用工廠方法模式、代理模式和享元模式修正。
策略模式的擴展(工廠方法模式+策略模式)

    首先策略枚舉StrategyMan,負責對具體策略的映射,然后建立一個簡單的工廠,根據策略管理類的枚舉項創建一個策略對象,簡單而實用,策略模式的缺陷得到了彌補。其通用類圖如下:

  • public enum StrategyMan {
        Strategy1("com.strategy.ConcreteStrategy1"),
        Strategy2("com.strategy.ConcreteStrategy2");
        String value = "";
        private StrategyMan(String value){
            this.value = value;
        }
        public String getValue(){
            return this.value;
        }
    }
    
    public class StrategyFactory {
        public static IStrategy getStrategy(StrategyMan strategyman){
            IStrategy strategy = null;
            try {
                strategy = (IStrategy) Class.forName(strategyman.getValue()).newInstance();
            } catch (InstantiationException | IllegalAccessException
                    | ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return strategy;
        }
    }
    
    public class StrategyFacade {
        public void doSomething(String str){
            StrategyMan sMan = null;
            if(str.equalsIgnoreCase("Strategy1")){
                sMan = StrategyMan.Strategy1;
            }else if(str.equalsIgnoreCase("Strategy2")){
                sMan = StrategyMan.Strategy2;
            }
            IStrategy strategy = StrategyFactory.getStrategy(sMan);
            Context context = new Context(strategy);
            context.doSomething();
        }
    }
    
    public class Client {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            StrategyFacade sFacade = new StrategyFacade();
            sFacade.doSomething("Strategy1");
        }
    }
    View Code


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM