• java 装饰者模式


        《Head First 设计模式》学习中

    装饰者模式

    • 动态的将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案

    类图

                    

    参与者

        1.Component(被装饰对象的基类)

          定义一个对象接口,可以给这些对象动态地添加职责。

        2.ConcreteComponent(具体被装饰对象)

          定义一个对象,可以给这个对象添加一些职责。

        3.Decorator(装饰者抽象类)

          维持一个指向Component实例的引用,并定义一个与Component接口一致的接口。

        4.ConcreteDecorator(具体装饰者)

          具体的装饰对象,给内部持有的具体被装饰对象,增加具体的职责。

    涉及角色

    • 抽象组件:定义一个抽象接口,来规范准备附加功能的类
    • 具体组件:将要被附加功能的类,实现抽象构件角色接口
    • 抽象装饰者:持有对具体构件角色的引用并定义与抽象构件角色一致的接口
    • 具体装饰:实现抽象装饰者角色,负责对具体构件添加额外功能。

    举例:

      经常去一个饭馆吃牛肉面,可以选择添加鸡蛋,火腿,豆皮等配菜,这就可以使用装饰者模式。

     

     

    Component(被装饰对象的基类)

     

    package com.Observer.model;
    
    public abstract class food {
    	String  size;
    	
    	String description;
    	
    	
    	public String getSize() {
    		return size;
    	}
    
    
    	public void setSize(String size) {
    		this.size = size;
    	}
    
    
    	public String getDescription() {
    		return description;
    	}
    
    
    	public abstract  double cost();
    }
    

     

    ConcreteComponent(具体被装饰对象)

    package com.Observer.model;
    
    public class BeefNoodles extends food {
    
    	public BeefNoodles() {
    			description = "牛肉面小碗";
    	}
    
    	@Override
    	public double cost() {
    		if (super.getSize().equals("大碗")) {
    			super.description = "牛肉面大碗";
    			return 12.0;
    		}
    		super.description = "牛肉面小碗";
    		return 10.0;
    	}
    
    }
    
    package com.Observer.model;
    
    public class Casserole extends food {
    	
    	public Casserole(){
    		description = "砂锅方便面";
    	}
    	
    	@Override
    	public double cost() {
    		
    		return 12.0;
    	}
    
    }
    

    Decorator(装饰者抽象类) 

    package com.Observer.model;
    
    public  abstract class Condiment  extends food {
    	
    	public abstract String getDescription();
    }
    

    ConcreteDecorator(具体装饰者)

    package com.Observer.model;
    
    public class Ham extends Condiment  {
    
    	food food;
    	
    	public Ham(food food){
    		this.food =  food;
    	}
    	
    	@Override
    	public String getDescription() {
    		
    		return food.getDescription() + ", 火腿";
    	}
    
    	@Override
    	public double cost() {
    		return 2.0 + food.cost();
    	}
    
    }
    
    package com.Observer.model;
    
    public class Egg extends Condiment  {
    
    	food food;
    	
    	public Egg(food food){
    		this.food =  food;
    	}
    	
    	@Override
    	public String getDescription() {
    		
    		return food.getDescription() + ", 鸡蛋";
    	}
    
    	@Override
    	public double cost() {
    		return 1.5 + food.cost();
    	}
    
    }
    
    package com.Observer.model;
    
    public class Rosa extends Condiment  {
    
    	food food;
    	
    	public Rosa(food food){
    		this.food =  food;
    	}
    	
    	@Override
    	public String getDescription() {
    		
    		return food.getDescription() + ", 豆皮";
    	}
    
    	@Override
    	public double cost() {
    		
    		return 1.0 + food.cost();
    	}
    
    }  

     测试 

    package com.Observer.model;
    
    public class Test {
    	public static void main(String[] args) {
    		food food = new Casserole();
    		 System.out.println(food.getDescription() + "  价格  ," + food.cost() + "元");
    		 
    		 
    		 food food1 = new BeefNoodles();
    		 food1.setSize("大碗");
    		 food1  = new Ham(food1);
    		 food1  = new Ham(food1);
    		 food1  = new Egg(food1);
    		 food1  = new Rosa(food1);
    		 System.out.println(food1.getDescription() + "   价格 ," + food1.cost() + "元");
    		 
    		 
    		 food food2 = new BeefNoodles();
    		 food2.setSize("小碗");
    		 food2  = new Ham(food2);
    		 food2  = new Ham(food2);
    		 food2  = new Egg(food2);
    		 food2  = new Rosa(food2);
    		 System.out.println(food2.getDescription() + "   价格 ," + food2.cost() + "元");
    	}
    }
    

     结果 

    砂锅方便面  价格  ,12.0元
    牛肉面小碗, 火腿, 火腿, 鸡蛋, 豆皮   价格 ,18.5元
    牛肉面小碗, 火腿, 火腿, 鸡蛋, 豆皮   价格 ,16.5元
    

     要点:

    • 继承属于扩展形式之一,但不见得是达到弹性设计的最佳方案。
    • 在我们的设计中,应该允许行为可以被扩展,而不须修改现有的代码。
    • 组合和委托可用于在运行时动态地加上新的行为。
    • 除了继承,装饰者模式也可以让我们扩展行为。
    • 装饰者模式意味着一群装饰者类, 这些类用来包装具体组件。
    • 装饰者类反映出被装饰的组件类型(实际上,他们具有相同的类型,都经过接口或继承实现)。
    • 装饰者可以在被装饰者的行为前面与/或后面加上自己的行为,甚至将被装饰者的行为整个取代掉,而达到特定的目的。
    • 你可以有无数个装饰者包装一个组件。
    • 装饰者一般对组建的客户是透明的,除非客户程序依赖于组件的具体类型。 

     参考博客:https://www.cnblogs.com/chenxing818/p/4705919.html

      

      

     

  • 相关阅读:
    赶紧收藏吧!MyBatis-Plus万字长文图解笔记,错过了这个村可就没这个店了
    这篇建议java开发都看看,对Java方法及加深理解的很深,值得一看!
    秒极啊!手把手带你进行shiro授权拦截器的重写,学到了学到了
    java面试复习重点:类的管理及常用工具,教你抓住面试的重点!
    手撸一个外卖点餐系统后台,可以写上简历的实战项目!
    JVM类加载机制详解,建议看这一篇就够了,深入浅出总结的十分详细!
    这份SpringMVC执行原理笔记,建议做java开发的好好看看,总结的很详细!
    iOS-----GitHub上比较齐全的iOS 工具和App
    iOS-----AVFoundation框架的功能详解
    iOS-----UIScrollView
  • 原文地址:https://www.cnblogs.com/chenlizhi/p/7811689.html
Copyright © 2020-2023  润新知