• Java与设计模式-策略模式


         在实际开发中,可能会遇到这样一个情况,某一功能的实现分为多种算法,这些算法能够认定为策略,在实际操作时选择不同算法或策略进行操作得出终于结果。在实际生活中。这些样例也是举不胜举。比如。商场举行活动,满100元减10元,满200元减30元,满500元减100元等等...这样每消费一笔,依据这一笔钱消费的多少。计算终于应支付的钱相应着不同的算法,这些相应的不同计算方法就能够认定为是不同的策略。

    在某东购物时,依据不同的用户等级,打折力度也是不同的。

        策略模式的UML类图參照下图:

      

        假如没有策略模式。实现某东购物计算终于付款的方法如何呢?

       

    package com.strategy.demo;
    
    public class NoStrategy {
    	/**
    	 * 不使用測量模式实现
    	 * @param args
    	 */
    	private static final int NOCARDUSER=1;
    	private static final int IRONCARDUSER=2;
    	private static final int GOLDCARDUSER=3;
    	
    
    	public static void main(String[] args) {
    		NoStrategy NoStrategy1=new NoStrategy();
    		NoStrategy NoStrategy2=new NoStrategy();
    		NoStrategy NoStrategy3=new NoStrategy();
    		
    		System.out.println("没有卡牌的买家买100元货物终于应付款:"+NoStrategy1.getPrice(100.0, 1));
    		
    		System.out.println("铁牌的买家买100元货物终于应付款:"+NoStrategy2.getPrice(100.0, 2));
    		
    		System.out.println("金牌的买家买100元货物终于应付款:"+NoStrategy3.getPrice(100.0, 3));
    
    	}
    	
    	
    	private double getNoCardPrice(double price){
    		 return price;
    	}
    	
    	private double getIronCardPrice(double price){
    		 return price*0.9;
    	}
    	
    	private double getGoldCardPrice(double price){
    		 return price*0.7;
    	}
    	
    	
    	private double getPrice(double price,int type){
    		 if(type==NOCARDUSER){
    			 return getNoCardPrice(price);
    		 }else if(type ==IRONCARDUSER){
    			 return getIronCardPrice(price);
    		 }else if(type ==GOLDCARDUSER){
    			 return getGoldCardPrice(price);
    		 }else {
    			 return 0;
    		 }
    	}
    
    }
    


    执行实例:

    呀,得出正确的答案了,这时你是不是应该满足了呢。应该高枕无忧了呢?突然,主管说要添加钻石用户的类别,钻石用户打六折,这时你怎么实现呢?在里面在添加钻石用户的类型,再添加计算钻石用户的方法,再再最后的推断里添加i f else?  这种确能够实现功能,可是是不是不满足开闭原则呢?并且随着用户种类的不断添加,你的if  else是不是也越来越长,逻辑也越来越复杂呢?导致系统扩展性和稳定性越来越差呢? 所以,这种方式在实际中显然实不可取的,以下我们看一下怎样使用策略模式来实现上面的需求。

    1.PriceStrategyInterface 接口,相应UML类图中的Strategy接口:

    package com.strategy.demo;
    
    public interface PriceStrategyInterface {
    
    	double calPrice(double price);
    }
    


    2.实现类,无卡用户:

    package com.strategy.demo;
    
    public class NoCardUserStrategy implements PriceStrategyInterface {
    	/**
    	 * 无牌买家。原价
    	 */
    
    	@Override
    	public double calPrice(double price) {
    		return price;
    	}
    
    }
    


    3.实现类。铁卡用户:

    package com.strategy.demo;
    
    public class IronCardUserStrategy implements PriceStrategyInterface {
    	/*
    	 * 铁牌买家
    	 * (non-Javadoc)
    	 * @see com.strategy.demo.PriceStrategyInterface#calPrice(double)
    	 */
    
    	@Override
    	public double calPrice(double price) {
    		return price*0.9;
    	}
    
    }
    


    4.实现类。金卡用户:

    package com.strategy.demo;
    
    public class GoldCardUserStrategy implements PriceStrategyInterface {
    	/**
    	 * 金牌买家
    	 */
    
    	@Override
    	public double calPrice(double price) {
    		return price*0.7;
    	}
    
    }
    


    5.环境对象。用来操作策略:

    package com.strategy.demo;
    
    public class PriceContext {
    	/**
    	 * 操作类
    	 */
    
    	PriceStrategyInterface priceStrategyInterface;
    	/*
    	 * 通过初始化传入对象
    	 */
    	public PriceContext(PriceStrategyInterface priceStrategyInterface) {
    		this.priceStrategyInterface=priceStrategyInterface;
    	}
    	/*
    	 * 通过对象计算返回值
    	 */
    	public double getPrice(double price){
    		 return priceStrategyInterface.calPrice(price);
    	}
    }
    

    环境对象初始化时。将相应的策略对象传入,然后调用方法返回计算值。

    6.构建測试类,測试:

    package com.strategy.demo;
    
    public class TestClass {
    
    	public static void main(String[] args) {
    		PriceContext priceContext=new PriceContext(new NoCardUserStrategy());
    		System.out.println("没有卡牌的买家买100元货物终于应付款:"+priceContext.getPrice(100.0));
    		
    		PriceContext priceContext2=new PriceContext(new IronCardUserStrategy());
    		System.out.println("铁牌的买家买100元货物终于应付款:"+priceContext2.getPrice(100.0));
    		
    		PriceContext priceContext3=new PriceContext(new GoldCardUserStrategy());
    		System.out.println("金牌的买家买100元货物终于应付款:"+priceContext3.getPrice(100.0));
    
    	}
    
    }
    

    执行上面的实例:

    得到了和第一个方法一样的正确答案,这时我们假如要添加一个钻石买家的种类。怎么实现呢?我们仅仅须要添加一个策略实现类:

    package com.strategy.demo;
    
    public class DiamondUserStrategy implements PriceStrategyInterface {
    
    	@Override
    	public double calPrice(double price) {
    		return price*0.6;
    	}
    
    }
    


    然后測试类添加一条钻石类买家的购物:

    package com.strategy.demo;
    
    public class TestClass {
    
    	public static void main(String[] args) {
    		PriceContext priceContext=new PriceContext(new NoCardUserStrategy());
    		System.out.println("没有卡牌的买家买100元货物终于应付款:"+priceContext.getPrice(100.0));
    		
    		PriceContext priceContext2=new PriceContext(new IronCardUserStrategy());
    		System.out.println("铁牌的买家买100元货物终于应付款:"+priceContext2.getPrice(100.0));
    		
    		PriceContext priceContext3=new PriceContext(new GoldCardUserStrategy());
    		System.out.println("金牌的买家买100元货物终于应付款:"+priceContext3.getPrice(100.0));
    		
    		PriceContext priceContext4=new PriceContext(new DiamondUserStrategy());
    		System.out.println("钻石卡的买家买100元货物终于应付款:"+priceContext4.getPrice(100.0));
    
    	}
    
    }
    


    执行实例:



    是不是扩展起来特别easy?条理也十分清晰。总结一下策略模式的长处:

    1. 结构清晰,使用简单直观。

    2. 系统耦合性减少。扩展方便;

    3. 操作封装彻底。数据更为安全。(在TestClass中,仅仅知道相关实现类,并不涉及详细计算方法)

    当然,策略方式也存在一定的缺点:

    由图能够直观的看出,随着策略的不断添加。子类数量变得庞大。

    喜欢的朋友关注我和我的微信平台

       

  • 相关阅读:
    Java openrasp学习记录(一)
    Java ASM3学习(3)
    Java ASM3学习(2)
    Java Instrumentation插桩技术学习
    Java ASM3学习(1)
    从JDK源码学习HashSet和HashTable
    从JDK源码学习HashMap
    从JDK源码学习ArrayList
    Java XXE漏洞典型场景分析
    CVE-2020-7961 Liferay Portal 复现分析
  • 原文地址:https://www.cnblogs.com/jhcelue/p/7098484.html
Copyright © 2020-2023  润新知