您当前的位置: 首页 >  Java

小志的博客

暂无认证

  • 0浏览

    0关注

    1217博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

java设计模式——装饰者模式

小志的博客 发布时间:2020-06-22 22:53:46 ,浏览量:0

目录
    • 一、装饰者模式的定义与类型
    • 二、装饰者模式的适用场景
    • 三、装饰者模式的优点
    • 四、装饰者模式的缺点
    • 五、装饰者模式相关的设计模式
    • 六、普通示例:
    • 七、普通示例演进,使用装饰者模式示例:

一、装饰者模式的定义与类型

1、定义

  • 在不改变原有对象的基础之上,将功能附加到对象上
  • 提供了比继承更具有弹性的替代方法(扩展原有对象功能)

2、类型

  • 结构型
二、装饰者模式的适用场景
  • 扩展一个类的功能或给一个类添加附加职责
  • 动态的给一个对象添加功能,这些功能可以在动态的撤销
三、装饰者模式的优点
  • 继承的有力补充,比继承灵活,不改变原有对象的情况下给一个对象扩展功能
  • 通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同效果
  • 符合开闭原则
四、装饰者模式的缺点
  • 会出现更多的代码,更多的类,增加程序复杂性
  • 动态装饰时,多层装饰时会更复杂
五、装饰者模式相关的设计模式
  • 装饰者模式和代理模式
  • 装饰者模式和适配器模式
六、普通示例:

示例描述:创建一个煎饼类、加鸡蛋的煎饼类,加鸡蛋和香肠的煎饼类,并获取相应的描述和价格 该示例如果煎饼加2个、3、4、5个等鸡蛋或者煎饼的话,扩展会麻烦

1、定义一个煎饼类

package com.rf.designPatterns.structural.decorator.v1;
/**
 * @description: 煎饼类
 * @author: xiaozhi
 * @create: 2020-06-22 21:30
 */
public class Pancakes {
    //获取描述的方法 protected在子类中可以重写
    protected String getDesc(){
        return "煎饼";
    }
    //获取价格的方法
    protected int getPrice(){
        return 8;
    }
}

2、定义一个加一个鸡蛋的煎饼类

package com.rf.designPatterns.structural.decorator.v1;
/**
 * @description: 加一个鸡蛋的煎饼类
 * @author: xiaozhi
 * @create: 2020-06-22 21:35
 */
public class PancakesWithEgg extends Pancakes{
    @Override
    public String getDesc() {
        return super.getDesc()+"加一个鸡蛋";
    }
    @Override
    public int getPrice() {
        return super.getPrice()+1;
    }
}

3、 定义一个加一个鸡蛋并且加一个香肠的煎饼类

package com.rf.designPatterns.structural.decorator.v1;

/**
 * @description: 加一个鸡蛋并且加一个香肠的煎饼类
 * @author: xiaozhi
 * @create: 2020-06-22 21:37
 */
public class PancakesWithSausage  extends PancakesWithEgg{
    @Override
    public String getDesc() {
        return super.getDesc()+"加一个香肠";
    }
    @Override
    public int getPrice() {
        return super.getPrice()+2;
    }
}

4、定义一个测试类

package com.rf.designPatterns.structural.decorator.v1;

/**
 * @description: 测试类
 * @author: xiaozhi
 * @create: 2020-06-22 21:38
 */
public class Test {
    public static void main(String[] args) {
        Pancakes pancakes = new Pancakes();
        System.out.println(pancakes.getDesc()+"销售价格为:"+pancakes.getPrice());

        Pancakes pancakesWithEgg = new PancakesWithEgg();
        System.out.println(pancakesWithEgg.getDesc()+"销售价格为:"+pancakesWithEgg.getPrice());

        Pancakes pancakesWithSausage = new PancakesWithSausage();
        System.out.println(pancakesWithSausage.getDesc()+"销售价格为:"+pancakesWithSausage.getPrice());

    }
}

5、输出效果图下图: 在这里插入图片描述 6、类图如下: 在这里插入图片描述

七、普通示例演进,使用装饰者模式示例:

装饰者模式4个角色:抽象的实体类、具体的实体类、抽象的装饰者、确定的装饰者 在该示例中:被装饰者是煎饼;装饰者是鸡蛋和香肠

1、定义一个抽象的煎饼实体类

package com.rf.designPatterns.structural.decorator.v2;
/**
 * @description:  定义一个抽象的煎饼实体类
 * @author: xiaozhi
 * @create: 2020-06-22 22:22
 */
public abstract class ABpancakes {
    //获取描述的抽象方法
    protected abstract String getDesc();
    //获取价格的抽象方法
    protected abstract int getPrice();
}

2、定义一个具体的煎饼实体类,继承抽象的煎饼实体类,并重写方法

package com.rf.designPatterns.structural.decorator.v2;
/**
 * @description: 定义一个具体的煎饼实体类,继承抽象的煎饼实体类,并重写方法
 * @author: xiaozhi
 * @create: 2020-06-22 22:25
 */
public class Pancakes extends ABpancakes{
    @Override
    protected String getDesc() {
        return "煎饼";
    }
    @Override
    protected int getPrice() {
        return 8;
    }
}

3、定义一个抽象的装饰者类,继承抽象的煎饼实体类并重写方法,该类是否定义为抽象类,因场景而定

package com.rf.designPatterns.structural.decorator.v2;
/**
 * @description: 定义一个抽象的装饰者类,继承抽象的煎饼实体类并重写方法
 *               该类是否定义为抽象类,因场景而定
 * @author: xiaozhi
 * @create: 2020-06-22 22:28
 */
public class AbstractDecorator extends  ABpancakes{
    //通过构造方法注入抽象的煎饼实体类
    private  ABpancakes aBpancakes;
    public AbstractDecorator(ABpancakes aBpancakes) {
        this.aBpancakes = aBpancakes;
    }
    @Override
    protected String getDesc() {
        return this.aBpancakes.getDesc();//获取描述
    }
    @Override
    protected int getPrice() {
        return this.aBpancakes.getPrice();//获取价格
    }
}

4、定义一个鸡蛋的装饰者类,继承抽象的装饰者类,并实现抽象的装饰者类的构造器

package com.rf.designPatterns.structural.decorator.v2;
/**
 * @description: 定义一个鸡蛋的装饰者类,继承抽象的装饰者类,并实现抽象的装饰者类的构造器
 * @author: xiaozhi
 * @create: 2020-06-22 22:31
 */
public class EggDecorator extends AbstractDecorator{
    public EggDecorator(ABpancakes aBpancakes) {
        super(aBpancakes);
    }
    @Override
    protected String getDesc() {
        return super.getDesc()+"加一个鸡蛋,";
    }
    @Override
    protected int getPrice() {
        return super.getPrice()+1;
    }
}

5、定义一个香肠的装饰者类,继承抽象的装饰者类,并实现抽象的装饰者类的构造器

package com.rf.designPatterns.structural.decorator.v2;
/**
 * @description: 定义一个香肠的装饰者类,继承抽象的装饰者类,并实现抽象的装饰者类的构造器
 * @author: xiaozhi
 * @create: 2020-06-22 22:31
 */
public class SausageDecorator extends AbstractDecorator{
    public SausageDecorator(ABpancakes aBpancakes) {
        super(aBpancakes);
    }
    @Override
    protected String getDesc() {
        return super.getDesc()+"加一根香肠,";
    }
    @Override
    protected int getPrice() {
        return super.getPrice()+2;
    }
}

6、定义一个测试类

package com.rf.designPatterns.structural.decorator.v2;
/**
 * @description: 测试类
 * @author: xiaozhi
 * @create: 2020-06-22 22:38
 */
public class Test {
    public static void main(String[] args) {
        ABpancakes aBpancakes;//创建一个抽象的煎饼实体类
        aBpancakes=new Pancakes();//创建一个具体的煎饼实体类
        aBpancakes=new EggDecorator(aBpancakes);//创建一个加鸡蛋的煎饼类
        aBpancakes=new EggDecorator(aBpancakes);//再创建一个加鸡蛋的煎饼类
        aBpancakes=new SausageDecorator(aBpancakes);//再创建一个加香肠的煎饼类
        System.out.println(aBpancakes.getDesc()+" 销售价格:"+aBpancakes.getPrice());
    }
}

7、输出结果如下: 在这里插入图片描述

8、类图如下: 在这里插入图片描述

关注
打赏
1661269038
查看更多评论
立即登录/注册

微信扫码登录

0.4822s