zoukankan      html  css  js  c++  java
  • 设计模式入门之装饰器模式Decorator

    //装饰模式定义:动态地给一个对象加入一些额外的职责。
    //就添加功能来说。装饰模式比生成子类更为灵活
    //这也提现了面向对象设计中的一条基本原则,即:尽量使用对象组合,而不是对象继承
    //Component:组件对象的接口。能够给这些对象动态加入职责
    //ConcreateComponet:详细的组件对象。实现组件对象接口。通常就是被装饰器装饰的对象。也就是能够给这个对象加入职责
    //Decorator:全部装饰器的抽象父类,须要定义一个与组件接口一致的接口,并持有一个Component对象,即被装饰的对象
    //在Java中比較常见的一种装饰器模式体现例如以下:
    //new DataInputStream(new BufferedInputStream(new FileInputStream("IOtest.txt")));
    //FileInputStream完毕他自己的功能。然后由装饰器完毕须要添加的功能
    //实例:设计一个奖金系统,奖金有月奖金,累计奖金和团队奖金,依据不同的人发不同的奖金
    //不使用装饰模式的实现中,各个奖金模块的耦合非常严重,当有新的奖励方法时修改非常多,扩展不方便
    //以下是使用了装饰模式的实现方式:
    //数据库模拟类。存储人员销售额,模拟。仅仅给了一个月的销售额
    public class TempDB {
    	private TempDB() {
    	}
    	public static Map<String, Double> mapMonthSaleMoney = new HashMap<String, Double>();
    	static {
    		mapMonthSaleMoney.put("张三", 10000.0);
    		mapMonthSaleMoney.put("李四", 20000.0);
    		mapMonthSaleMoney.put("王五", 30000.0);
    	}
    }
    //全部奖励方法的父类,标准实现使用了抽象类
    public abstract class PrizeCalculor {
    	public abstract double calcPrize(String user, Date begin, Date end);
    }
    //须要被装饰的对象类,比方每一个人每一个月都会有500块的基本奖金
    public class NormalPrizeCalc extends PrizeCalculor {
    	public double calcPrize(String user, Date begin, Date end) {
    		return 500;
    	}
    }
    //以下是装饰器的父类
    public abstract class Decorator extends PrizeCalculor{
    	protected PrizeCalculor c;//被装饰的对象
    	public Decorator(PrizeCalculor c) {
    		this.c = c;
    	}
    	public double calcPrize(String user, Date begin, Date end) {
    		//前后可添加功能
    		return this.c.calcPrize(user, begin, end);//默认直接转调被装饰对象的方法
    	}
    }
    //月奖金装饰器类
    public class MonthPrizeDecorator extends Decorator{
    	public MonthPrizeDecorator(PrizeCalculor c) {
    		super(c);
    	}
    	public double calcPrize(String user, Date begin, Date end) {
    		double money = super.calcPrize(user, begin, end);//先获得被装饰对象的奖金
    		double prize = TempDB.mapMonthSaleMoney.get(user)*0.03;//计算月奖金
    		System.out.println(user+"当月业务奖金"+prize);
    		return money+prize;//返回被装饰对象的总奖金
    	}
    }
    //累计奖金装饰器类。作用同上
    public class SumPrizeDecorator extends Decorator{
    	public SumPrizeDecorator(PrizeCalculor c) {
    		super(c);
    	}
    	public double calcPrize(String user, Date begin, Date end) {
    		double money = super.calcPrize(user, begin, end);
    		double prize = 100000*0.001;//如果全部人的累计销售额都是100000
    		System.out.println(user+"累计奖金"+prize);
    		return money+prize;
    	}
    }
    //团队奖金装饰器类,仅仅有项目经理才有
    public class GroupPrizeDecorator extends Decorator{
    	public GroupPrizeDecorator(PrizeCalculor c) {
    		super(c);
    	}
    	public double calcPrize(String user, Date begin, Date end) {
    		double money = super.calcPrize(user, begin, end);
    		double group = 0.0;
    		for(double d : TempDB.mapMonthSaleMoney.values()) {
    			group += d;
    		}
    		double prize = group * 0.01;
    		System.out.println(user+"当月团队业务奖金"+prize);
    		return money + prize;
    	}
    }
    //client測试类
    public class Client {
    	public static void main(String[] args) {
    		PrizeCalculor calc = new NormalPrizeCalc();
    		Decorator d1 = new MonthPrizeDecorator(calc);
    		Decorator d2 = new SumPrizeDecorator(d1);
    		//把被装饰对象进行组合,calc对象经d1装饰。然后d1对象经d2装饰
    		double zs = d2.calcPrize("张三", null, null);
    		System.out.println(zs);
    		double ls = d2.calcPrize("李四", null, null);
    		System.out.println(ls);
    		Decorator d3 = new GroupPrizeDecorator(d2);
    		//项目经理。d2对象再经d3对象装饰
    		double ww = d3.calcPrize("王五", null, null);
    		System.out.println(ww);
    	}
    }
    //装饰模式的本质:动态组合
    //装饰器模式长处:比继承更加灵活,更容复用功能,简化高层定义
    //装饰器模式缺点:会产生非常多细粒度对象
    //注意:各个装饰器之间最好是全然独立的功能,不要有依赖,这样在进行装饰组合的时候。才没有先后顺序的限制。也就是先装饰谁和后装饰谁都是一样的。否则会大大减少装饰漆组合的灵活性

  • 相关阅读:
    python学习之路(3)
    扫描工具-Nikto
    python学习之路(2)(渗透信息收集)
    openvas 安装
    python 学习之路(1)
    BZOJ4004:[JLOI2015]装备购买——题解
    HDU3949:XOR——题解
    洛谷3812:【模板】线性基——题解
    BZOJ4566:[HAOI2016]找相同字符——题解
    BZOJ3238:[AHOI2013]差异——题解
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5067928.html
Copyright © 2011-2022 走看看