美文网首页
装饰器模式(Decoretor Pattern)

装饰器模式(Decoretor Pattern)

作者: 吉他手_c156 | 来源:发表于2020-04-17 00:13 被阅读0次

    装饰器模式(decoretor pattern)也称为包装器模式(wrapper pattern),是指在不改变原有对象的基础上,动态的将功能附加到对象上,属于结构型模式

    装饰器的结构与特点

    装饰器模式主要包含以下角色

    1.抽象构建(Component)角色,定义抽象构建规定具体构建要实现的方法
    2.具体构建(Concrete Component)角色,实现抽象构建,使用装饰器为其添加一些职责
    3.抽象装饰(Decoretor)角色,继承抽象构建,并包含具体构建的实例,扩展具体构建的功能
    4.具体装饰(Concrete Decoretor)角色,实现抽象装饰,并给具体构建添加扩展的责任

    装饰器模式的优缺点

    优点
    1.采用装饰器扩展对象的功能比继承更灵活
    2.可以设计出不同的具体装饰类,创造出多个不同的行为组合
    缺点
    1.装饰模式增加了许多子类,如果过度使用会增加系统的复杂度

    装饰器模式的应用

    创建抽象构建,规定具体构建要实现的方法

    /**
     * Componetn 规定具体构建要实现的方法
     */
    public abstract class BatterCake {
    
        public abstract String getMsg();
        public abstract int price();
    }
    

    创建具体构建,实现抽象构建的方法

    /**
     * 具体构建 Concrete Component 实现抽象构建的方法,使用装饰器为其附加职责
     */
    public class BaseBatterCake extends BatterCake {
    
        @Override
        public String getMsg() {
            return "煎饼";
        }
    
        @Override
        public int price() {
            return 5;
        }
    }
    

    创建抽象装饰器,继承具体构建,并包含具体构建的引用,规定子类必须实现的构造方法,这里的方法不做实现,引用具体构建的方法

    /**
     * 抽象装饰器 Decoretor 这是继承抽象构建,并包含具体构件的实例
     * 这里的方法不做具体实现,调用被装饰类的方法
     */
    public class BatterCakeDecoretor extends BatterCake{
    
        private BatterCake batterCake;
    
        // 规定子类必须实现的构造方法
        public BatterCakeDecoretor(BatterCake batterCake){
            this.batterCake = batterCake;
        }
    
        @Override
        public String getMsg() {
            return this.batterCake.getMsg();
        }
    
        @Override
        public int price() {
            return this.batterCake.price();
        }
    }
    

    创建具体装饰器实现抽象装饰器,并给具体构建扩展新的功能

    /**
     * 具体装饰器 Concrete Decoretor
     * 实现抽象装饰器,并给具体构建添加扩展职责
     */
    public class EggDecoretor extends BatterCakeDecoretor {
        public EggDecoretor(BatterCake batterCake) {
            super(batterCake);
        }
    
        @Override
        public String getMsg() {
            return super.getMsg()+",+1个鸡蛋";
        }
    
        @Override
        public int price() {
            return super.price()+1;
        }
    }
    
    /**
     * 具体装饰器 Concrete Decoretor
     * 实现抽象装饰器,并给具体构建添加扩展职责
     */
    public class PancakesDecoretor extends BatterCakeDecoretor {
        public PancakesDecoretor(BatterCake batterCake) {
            super(batterCake);
        }
    
        @Override
        public String getMsg() {
            return super.getMsg()+",+1个火腿";
        }
    
        @Override
        public int price() {
            return super.price()+2;
        }
    }
    

    测试

        public static void main(String[] args) {
            System.out.println("=============测试一===========");
            // 创建一个煎饼
            BatterCake batterCake = new BaseBatterCake();
            System.out.println(batterCake.getMsg()+","+batterCake.price()+"块钱");
            // 给煎饼加一个鸡蛋
            BatterCakeDecoretor egg = new EggDecoretor(batterCake);
            System.out.println(egg.getMsg()+","+egg.price()+"块钱");
            // 给煎饼在加一根香肠
            BatterCakeDecoretor pancakes = new PancakesDecoretor(egg);
            System.out.println(pancakes.getMsg()+","+pancakes.price()+"块钱");
            // 给煎饼在加一个火腿
            BatterCakeDecoretor pancakes2 = new PancakesDecoretor(pancakes);
            System.out.println(pancakes2.getMsg()+","+pancakes2.price()+"块钱");
    
            System.out.println("=============测试2===========");
            // 给煎饼加两个鸡蛋一个火腿
            BatterCake cake = new PancakesDecoretor(new EggDecoretor(new EggDecoretor(new BaseBatterCake())));
            System.out.println(cake.getMsg()+","+cake.price()+"块钱");
        }
    }
    

    结果

    =============测试一===========
    煎饼,5块钱
    煎饼,+1个鸡蛋,6块钱
    煎饼,+1个鸡蛋,+1个火腿,8块钱
    煎饼,+1个鸡蛋,+1个火腿,+1个火腿,10块钱
    =============测试2===========
    煎饼,+1个鸡蛋,+1个鸡蛋,+1个火腿,9块钱
    
    装饰器模式实例应用

    需求:用户列表默认使用的是 Id 排序,现在需求要使用 age 排序,过了几天项目经理又说,使用 name 排序...悲催了!为了不影响原有功能,这里使用装饰器模式
    创建抽象构建

    /**
     * 抽象构建 Component 数访问层
     */
    public interface IUserService {
    
        public List<User> getUserList();
    }
    

    创建具体构建

    /**
     * 具体构建 Concrete Component 业务逻辑层
     */
    public class UserService implements IUserService{
    
    
        /**
         * 获取用户列表  默认根据用户 id 排序
         * @return
         */
        @Override
        public List<User> getUserList() {
            // 模拟查询到的数据
            List<User> userList = new ArrayList<User>(){};
            userList.add(new User(4, "张三",18));
            userList.add(new User(58, "李四",15));
            userList.add(new User(18, "王五",25));
            userList.add(new User(39, "张柳",48));
            userList.add(new User(14, "赵云",39));
            userList.add(new User(3, "蒙会",17));
            userList.sort(new Comparator<User>() {
                @Override
                public int compare(User o1, User o2) {
                    return o1.getId() - o2.getId();
                }
            });
            return userList;
        }
    }
    

    创建抽象装饰类,继承抽象构建,持有具体构建的引用

    /**
     * 抽象装饰器  Decoretor 继承抽象构建 持有具体构建的应用,规定子类必须实现的构造方法
     *
     */
    public abstract class UserSortDecoretor implements IUserService{
    
        private IUserService userService;
    
        public UserSortDecoretor(IUserService userService){
            this.userService = userService;
        }
    
        @Override
        public List<User> getUserList() {
            return userService.getUserList();
        }
    }
    

    创建具体装饰器,实现抽象装饰类,为具体构建添加新的功能

    /**
     * 具体装饰器Concrete Decoretor 实现抽象装饰,并给具体构建附加新的功能
     * 根据年龄排序
     */
    public class UserSortByAgeDecoretor extends UserSortDecoretor{
    
        public UserSortByAgeDecoretor(IUserService userService) {
            super(userService);
        }
    
        @Override
        public List<User> getUserList() {
            List<User> userList = super.getUserList();
            userList.sort(new Comparator<User>() {
                @Override
                public int compare(User o1, User o2) {
                    return o1.getAge()-o2.getAge();
                }
            });
            return userList;
        }
    }
    
    /**
     * 具体装饰器 Concrete Decoretor
     * 实现抽象装饰器,并给具体构建类添加新的功能
     */
    public class UserSortByNameDecoretor extends UserSortDecoretor {
    
        public UserSortByNameDecoretor(IUserService userService) {
            super(userService);
        }
    
        @Override
        public List<User> getUserList() {
            List<User> userList = super.getUserList();
            userList.sort(new Comparator<User>() {
                @Override
                public int compare(User o1, User o2) {
                    return o1.getName().compareTo(o2.getName());
                }
            });
            return userList;
        }
    }
    

    测试

        public static void main(String[] args) {
            IUserService idSort = new UserService();
            List<User> idSortList = idSort.getUserList();
    
    
            System.out.println("====================默认使用用户 id 排序==================");
            idSortList.forEach(user -> {
                System.out.println(user.getId()+","+user.getName()+","+user.getAge());
            });
    
            System.out.println("====================使用用户 age 排序==================");
            UserSortDecoretor ageSort = new UserSortByAgeDecoretor(idSort);
            List<User> ageSortList = ageSort.getUserList();
            ageSortList.forEach(user -> {
                System.out.println(user.getId()+","+user.getName()+","+user.getAge());
            });
    
            System.out.println("====================使用用户 name 排序==================");
            UserSortDecoretor nameSort = new UserSortByNameDecoretor(ageSort);
            List<User> nameSortList = nameSort.getUserList();
            nameSortList.forEach(user -> {
                System.out.println(user.getId()+","+user.getName()+","+user.getAge());
            });
        }
    

    结果

    ====================默认使用用户 id 排序==================
    3,蒙会,17
    4,张三,18
    14,赵云,39
    18,王五,25
    39,张柳,48
    58,李四,15
    ====================使用用户 age 排序==================
    58,李四,15
    3,蒙会,17
    4,张三,18
    18,王五,25
    14,赵云,39
    39,张柳,48
    ====================使用用户 name 排序==================
    4,张三,18
    39,张柳,48
    58,李四,15
    18,王五,25
    3,蒙会,17
    14,赵云,39
    

    相关文章

      网友评论

          本文标题:装饰器模式(Decoretor Pattern)

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