美文网首页
java - 装饰者模式

java - 装饰者模式

作者: 徘徊0_ | 来源:发表于2018-04-09 10:20 被阅读0次

    装饰者模式

    装饰者模式:动态将责任添加到对象上。如果需要扩展功能,装饰者提供了比继承更有弹性的解决方案。装饰者模式类图如下:


    装饰者模式类图(来源Head First).png

    举个栗子:
    情景如下:去饭店点菜的例子,饭店(Component),中国饭店(ConcreteComponent),菜品(Decorate),鱼(FishDecorate装饰者),牛排(SteakDecorate装饰者)

    • 被装饰者
      1,创建基类
    /**
     * 饭店
     * @author cuishuxiang
     */
    public abstract class Restaurant {
        //点菜
        String orderFood="Order Nothing";
        
        public String getOrderFoods() {
            return orderFood;
        }
        
        //根据点的菜,计算价格
        abstract int cost();
    }
    

    2,创建饭店的具体实现类

    /**
     * 中国餐馆
     * @author cuishuxiang
     */
    public class ChinaRestaurant extends Restaurant{
        
        public ChinaRestaurant() {
            // TODO Auto-generated constructor stub
        }
        
        @Override
        public String getOrderFoods() {
            // TODO Auto-generated method stub
            return super.getOrderFoods();
        }
    
        @Override
        int cost() {
            // 此时没点菜,价格为 0 
            return 0;
        }
    
    }
    
    • 装饰者(继承基类拥有同一个父类Restaurant
      1,创建装饰者基类
    /**
     * 抽象装饰者
     * @author cuishuxiang
     *
     */
    public abstract class Decorate extends Restaurant{
    
      public abstract String getOrderFoods();//点了什么菜
      
    }
    

    2,鱼(具体的装饰者)

    /**
     * 点了鱼
     * @author cuishuxiang
     *
     */
    public class FishDecorate extends Decorate{
        private Restaurant restaurant;
        
        public FishDecorate(Restaurant restaurant) {
            // 这里持有 Restaurant 的引用
            this.restaurant=restaurant;
        }
    
        @Override
        int cost() {
            // 此时应先计算上个的价格 再加上 鱼的价格
            return restaurant.cost()+10;
        }
    
        @Override
        public String getOrderFoods() {
            // TODO Auto-generated method stub
            return " 点了China饭店的 鱼!";
        }
    
    }
    

    3,牛排(具体的装饰者)

    /**
     * 牛排
     * 
     * @author cuishuxiang
     *
     */
    public class SteakDecorate extends Restaurant{
        Restaurant restaurant;
        
        public SteakDecorate(Restaurant restaurant) {
            this.restaurant=restaurant;
        }
        
        @Override
        public String getOrderFoods() {
            return restaurant.getOrderFoods()+",点了饭店的牛排。";
        }
        @Override
        int cost() {
            return restaurant.cost()+20;
        }
    
    }
    
    • 测试
    /**
     * 测试类
     * @author cuishuxiang
     */
    public class RestaurantTest {
    
        public static void main(String[] args) {
            Restaurant restaurant=new ChinaRestaurant();
            
            //装饰者,点了鱼(将引用传入)
            restaurant=new FishDecorate(restaurant);
            //装饰者,点了牛排
            restaurant=new SteakDecorate(restaurant);
                
            System.out.println("点的菜:"+restaurant.getOrderFoods());
                    
            System.out.println("总价为: "+restaurant.cost());
        }
    }
    

    结果为:


    装饰者测试结果.png 调用逻辑如上图.png
    总结
    • 装饰者模式特点
      1,装饰者与被装饰者拥有相同的父类(如上例中的Restaurant)。
      2,装饰者中都持有一个被装饰者的引用(如上例中构造器需要传入一个Restaurant引用)。
      3,装饰者执行完自己的逻辑之后,会将最终的结果传递给被装饰者(在装饰者类当中调用被装饰者类的方法,封装成新的功能方法。)。
      4,扩展性比较好,灵活性高。但是响应的会出现比较多的类。
      5,java中最常见的就是I/O,使用的就是装饰者模式。

    相关文章

      网友评论

          本文标题:java - 装饰者模式

          本文链接:https://www.haomeiwen.com/subject/onlmhftx.html