前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >结构型模式————装饰器模式(3.1)

结构型模式————装饰器模式(3.1)

作者头像
Noneplus
发布2019-09-24 16:05:08
2840
发布2019-09-24 16:05:08
举报
文章被收录于专栏:开发笔记开发笔记

什么是装饰器模式?

【先吃三颗栗子:】

1.PC=主机+显示器+键盘+鼠标+鼠标垫

主机是核心,而其他的组成部分都是装饰。

2.手抓饼=+鸡蛋+培根+黄瓜

饼是核心,鸡蛋,培根是可选的,可以理解为装饰。

3.咖啡=咖啡+牛奶+冰+方糖

咖啡是核心,牛奶等可选。

比喻虽然形象生动,但是与实际或多或少会产生偏差。

抽象的解释:装饰器模式的目的——核心部分和装饰部分可以自由组合。

装饰器模式的功能

对于软件开发来说,聚焦于软件的灵活性和可扩展性。

装饰器模式要求:

  • 装饰可选
  • 装饰可扩展
  • 核心部分可扩展

手抓饼中的装饰器模式

实现饼加各种配料的价格计算。

思路:

1.定义抽象类手抓饼,其中包含获取种类的抽象方法和获取价格的抽象方法。

2.然后定义两个分别为大份手抓饼和中份手抓饼来继承这个抽象类,重写两个方法定义种类和价格。

3.定义具体的配料类继承手抓饼抽象类,先定义构造器传入已经创建的手抓饼种类,然后重写种类和价格方法。

在网上看的一些博客,是创建出一个抽象的配料类来继承抽象产品类,然后用具体的配料类来实现抽象配料类,实现装饰。

可是如果直接将抽象产品类的方法全部定义抽象方法,配料类直接继承重写,实现装饰,功能上也是可以实现的,如下所示,Bacon类直接继承HandPancake,然后重写getName和getCost方法,实现装饰。似乎也没有问题:

但是设计模式毕竟是一种经验总结,如果有已经看出端倪的小伙伴们在下方留言交流一下吧!

直接继承HandPancake

代码语言:javascript
复制
abstract class HandPancake
{
    public abstract String getName();

    public abstract int getCost();
}

class HandPancake_Big extends HandPancake
{
    @Override
    public String getName() {
        return "大份手抓饼";
    }

    @Override
    public int getCost() {
        return 10;
    }
}

class HandPancake_Mid extends HandPancake
{
    @Override
    public String getName() {
        return "中份手抓饼";
    }

    @Override
    public int getCost() {
        return 8;
    }
}
class Bacon extends HandPancake
{
    private HandPancake handPancake;

    Bacon(HandPancake handPancake)
    {
        this.handPancake=handPancake;
    }

    @Override
    public String getName() {
        return handPancake.getName()+"加培根";
    }

    @Override
    public int getCost() {
        return handPancake.getCost()+1;
    }
}
class Cucumber extends HandPancake
{
    private HandPancake handPancake;

    Cucumber(HandPancake handPancake)
    {
        this.handPancake=handPancake;
    }

    @Override
    public String getName() {
        return handPancake.getName()+"加黄瓜";
    }

    @Override
    public int getCost() {
        return handPancake.getCost()+2;
    }
}
class Ham extends HandPancake
{
    private HandPancake handPancake;

    Ham(HandPancake handPancake)
    {
        this.handPancake=handPancake;
    }

    @Override
    public String getName() {
        return handPancake.getName()+"加火腿";
    }

    @Override
    public int getCost() {
        return handPancake.getCost()+1;
    }
}


public class APPlication
{
    public static void main(String[] args) {
        HandPancake handPancake_big = new HandPancake_Big();

        System.out.println("啥也不加"+handPancake_big.getName()+":"+handPancake_big.getCost());

        handPancake_big = new Ham(handPancake_big);

        System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());

        handPancake_big = new Cucumber(handPancake_big);

        System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());

        handPancake_big = new Bacon(handPancake_big);

        System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());

        System.out.println("==============================");
        HandPancake handPancake_mid = new HandPancake_Mid();
        System.out.println("啥也不加"+handPancake_mid.getName()+":"+handPancake_mid.getCost());

        handPancake_mid = new Ham(handPancake_mid);

        System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());

        handPancake_mid = new Cucumber(handPancake_mid);

        System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());

        handPancake_mid = new Bacon(handPancake_mid);

        System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());


    }
}
1565696683438
1565696683438

官方做法:

代码语言:javascript
复制
abstract class HandPancake
{
    String name;                      //1
    public  String getName()
    {
        return name;
    }

    public abstract int getCost();
}

class HandPancake_Big extends HandPancake
{
    HandPancake_Big()         //2.通过构造器赋值
    {
        name="大份手抓饼";
    }


    @Override
    public int getCost() {
        return 10;
    }
}

class HandPancake_Mid extends HandPancake
{
    HandPancake_Mid()         //2.通过构造器赋值
    {
        name="中份手抓饼";
    }


    @Override
    public int getCost() {
        return 8;
    }
}

abstract class Condiments  extends HandPancake   //3.定义抽象接口
{
    public abstract String getName();
}

class Bacon extends Condiments     //4.继承抽象接口
{
    private HandPancake handPancake;

    Bacon(HandPancake handPancake)
    {
        this.handPancake=handPancake;
    }

    @Override
    public String getName() {
        return handPancake.getName()+"加培根";
    }

    @Override
    public int getCost() {
        return handPancake.getCost()+1;
    }
}
class Cucumber extends Condiments
{
    private HandPancake handPancake;

    Cucumber(HandPancake handPancake)
    {
        this.handPancake=handPancake;
    }

    @Override
    public String getName() {
        return handPancake.getName()+"加黄瓜";
    }

    @Override
    public int getCost() {
        return handPancake.getCost()+2;
    }
}
class Ham extends Condiments
{
    private HandPancake handPancake;

    Ham(HandPancake handPancake)
    {
        this.handPancake=handPancake;
    }

    @Override
    public String getName() {
        return handPancake.getName()+"加火腿";
    }

    @Override
    public int getCost() {
        return handPancake.getCost()+1;
    }
}


public class APPlication
{
    public static void main(String[] args) {
        HandPancake handPancake_big = new HandPancake_Big();

        System.out.println("啥也不加"+handPancake_big.getName()+":"+handPancake_big.getCost());

        handPancake_big = new Ham(handPancake_big);

        System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());

        handPancake_big = new Cucumber(handPancake_big);

        System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());

        handPancake_big = new Bacon(handPancake_big);

        System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());

        System.out.println("==============================");
        HandPancake handPancake_mid = new HandPancake_Mid();
        System.out.println("啥也不加"+handPancake_mid.getName()+":"+handPancake_mid.getCost());

        handPancake_mid = new Ham(handPancake_mid);

        System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());

        handPancake_mid = new Cucumber(handPancake_mid);

        System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());

        handPancake_mid = new Bacon(handPancake_mid);

        System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());


    }
}
1565696715504
1565696715504

手抓饼的扩展性

  • 创建手抓饼的种类
  • 创建配料种类

官方的扩展:创建一个小份手抓饼继承Hanpancake,然后创建配料继承Condiments。

贴一下直接继承HandPancake的情况:

class HandPancake_Smalll extends HandPancake class Egg extends HandPancake

代码语言:javascript
复制
abstract class HandPancake
{
    public abstract String getName();

    public abstract int getCost();
}

class HandPancake_Big extends HandPancake
{
    @Override
    public String getName() {
        return "大份手抓饼";
    }

    @Override
    public int getCost() {
        return 10;
    }
}

class HandPancake_Mid extends HandPancake
{
    @Override
    public String getName() {
        return "中份手抓饼";
    }

    @Override
    public int getCost() {
        return 8;
    }
}
class Bacon extends HandPancake
{
    private HandPancake handPancake;

    Bacon(HandPancake handPancake)
    {
        this.handPancake=handPancake;
    }

    @Override
    public String getName() {
        return handPancake.getName()+"加培根";
    }

    @Override
    public int getCost() {
        return handPancake.getCost()+1;
    }
}
class Cucumber extends HandPancake
{
    private HandPancake handPancake;

    Cucumber(HandPancake handPancake)
    {
        this.handPancake=handPancake;
    }

    @Override
    public String getName() {
        return handPancake.getName()+"加黄瓜";
    }

    @Override
    public int getCost() {
        return handPancake.getCost()+2;
    }
}
class Ham extends HandPancake
{
    private HandPancake handPancake;

    Ham(HandPancake handPancake)
    {
        this.handPancake=handPancake;
    }

    @Override
    public String getName() {
        return handPancake.getName()+"加火腿";
    }

    @Override
    public int getCost() {
        return handPancake.getCost()+1;
    }
}
//========================

class HandPancake_Smalll extends HandPancake
{
    @Override
    public String getName() {
        return "小份手抓饼";
    }

    @Override
    public int getCost() {
        return 5;
    }
}


class Egg extends HandPancake
{
    private HandPancake handPancake;

    Egg(HandPancake handPancake)
    {
        this.handPancake=handPancake;
    }

    @Override
    public String getName() {
        return handPancake.getName()+"加鸡蛋";
    }

    @Override
    public int getCost() {
        return handPancake.getCost()+1;
    }
}


public class APPlication
{
    public static void main(String[] args) {
        HandPancake handPancake_big = new HandPancake_Big();

        System.out.println("啥也不加"+handPancake_big.getName()+":"+handPancake_big.getCost());

        handPancake_big = new Ham(handPancake_big);

        System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());

        handPancake_big = new Cucumber(handPancake_big);

        System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());

        handPancake_big = new Bacon(handPancake_big);

        System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());

        System.out.println("==============================");
        HandPancake handPancake_mid = new HandPancake_Mid();
        System.out.println("啥也不加"+handPancake_mid.getName()+":"+handPancake_mid.getCost());

        handPancake_mid = new Ham(handPancake_mid);

        System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());

        handPancake_mid = new Cucumber(handPancake_mid);

        System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());

        handPancake_mid = new Bacon(handPancake_mid);

        System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());


        System.out.println("扩展性测试:");

        HandPancake handPancake_small = new HandPancake_Smalll();
        System.out.println("啥也不加"+handPancake_small.getName()+":"+handPancake_small.getCost());

        handPancake_small = new Egg(handPancake_small);

        System.out.println(handPancake_small.getName()+":"+handPancake_small.getCost());






    }
}

运行结果:

1565696654138
1565696654138
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-08-13 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是装饰器模式?
  • 装饰器模式的功能
  • 手抓饼中的装饰器模式
  • 手抓饼的扩展性
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档