分披萨问题

问题陈述

我们需要为一家披萨公司构建软件,该公司想要准备不同类型的披萨,例如鸡肉披萨,扁平面包,意大利辣香肠披萨和特制奶酪,并在上面放些配料。

让我们尝试看看哪种设计模式适合该问题说明以及在哪种情况下。 传统上,对于披萨问题,最常用的是构造器模式。 但是,也有一些使用装饰器的示例,两种方法都是正确的,但用例有所不同。 Builder是一种对象创建模式,而装饰器用于在运行时更改已构建的对象。
让我们尝试通过示例来理解这一点:

  1. 生成器模式:

    这里的用例是按照既定规格一次性制作披萨。

    让我们来看看披萨课:

    public class Pizza {private float totalPrice = 0;private Size size;private Topping topping;private Crust crust;private Cheese cheese;public Size getSize() {return size;}public void setSize(Size size) {this.size = size;}public Topping getTopping() {return topping;}public void setTopping(Topping topping) {this.topping = topping;}public Crust getCrust() {return crust;}public void setCrust(Crust crust) {this.crust = crust;}public Cheese getCheese() {return cheese;}public void setCheese(Cheese cheese) {this.cheese = cheese;}public float getTotalPrice() {return totalPrice;}public void addToPrice(float price) {this.totalPrice = totalPrice + price;}
    }

    4个枚举类:

    public enum Cheese {AMERICAN {public float getCost() {return 40;}}, ITALIAN {public float getCost() {return 60;}};public abstract float getCost();}public enum Crust {THIN  {public float getCost(){return 70;}} , STUFFED{public float getCost(){return 90;}};public abstract float getCost();
    }public enum Size {MEDIUM {public float getCost() {return 100;}}, LARGE {public float getCost() {return 160;}};public abstract float getCost();
    }public enum Topping {PEPPERONI {public float getCost(){return 30;}}, CHICKEN{public float getCost(){return 35;}}, MUSHROOM{public float getCost(){return 20;}};public abstract float getCost();
    }

    PizzaBuilder类别:

    public class PizzaBuilder {Pizza pizza = new Pizza();public PizzaBuilder withTopping(Topping topping) {pizza.setTopping(topping);pizza.addToPrice(topping.getCost());return this;}public PizzaBuilder withSize(Size size) {pizza.setSize(size);pizza.addToPrice(size.getCost());return this;}public PizzaBuilder withCrust(Crust crust) {pizza.setCrust(crust);pizza.addToPrice(crust.getCost());return this;}public Pizza build() {return pizza;}public double calculatePrice() {return pizza.getTotalPrice();}}

    测试用例:

    public class PizzaBuilderTest {@Testpublic void shouldBuildThinCrustChickenPizza(){Pizza pizza = new PizzaBuilder().withCrust(Crust.THIN).withTopping(Topping.CHICKEN).withSize(Size.LARGE).build();assertEquals(Topping.CHICKEN,pizza.getTopping());assertEquals(Size.LARGE,pizza.getSize());assertEquals(Crust.THIN,pizza.getCrust());assertEquals(265.0,pizza.getTotalPrice(),0);}
    }
  2. 装饰图案:

    装饰器模式用于动态添加或删除对象的其他功能或职责,而不会影响原始对象。 用例是先准备一些基础比萨,然后再添加不同的规格。

    在这里,我们需要一个要装饰的BasicPizza(混凝土组件)的接口(Pizza),以及一个包含Pizza(已装饰)接口的引用字段的类PizzaDecorator。

    披萨界面:

    public interface Pizza {public String bakePizza();public float getCost();
    }

    基本比萨实施:

    public class BasePizza implements Pizza{public String bakePizza() {return "Basic Pizza";}public float getCost(){return 100;}
    }

    PizzaDecorator类:

    public class PizzaDecorator implements Pizza {Pizza pizza;public PizzaDecorator(Pizza newPizza) {this.pizza = newPizza;}public String bakePizza() {return pizza.bakePizza();}@Overridepublic float getCost() {return pizza.getCost();}
    }

    2个装饰器:蘑菇和意大利辣香肠

    public class Mushroom extends PizzaDecorator {public Mushroom(Pizza newPizza) {super(newPizza);}@Overridepublic String bakePizza() {return super.bakePizza() + " with Mashroom Topings";}@Overridepublic float getCost() {return super.getCost()+80;}
    }
    public class Pepperoni extends PizzaDecorator {public Pepperoni(Pizza newPizza) {super(newPizza);}@Overridepublic String bakePizza() {return super.bakePizza() + " with Pepperoni Toppings";}@Overridepublic float getCost() {return super.getCost()+110;}
    }

    测试用例:

    public class PizzaDecoratorTest {@Testpublic void shouldMakePepperoniPizza(){Pizza pizza = new Pepperoni(new BasePizza());assertEquals("Basic Pizza with Pepperoni Toppings",pizza.bakePizza());assertEquals(210.0,pizza.getCost(),0);}
    }

区别

在创建对象时使用了诸如builder和factory(以及abstract factory)之类的模式。 装饰器之类的模式(也称为结构设计模式)用于可扩展性或为已创建的对象提供结构更改。

两种类型的模式在很大程度上都偏重于组合而不是继承,因此将其作为使用生成器而不是装饰器的区分符没有任何意义。 两者都在运行时给出行为,而不是继承它。

因此,如果要限制使用某些属性/功能创建对象,则应使用builder。 例如,在创建对象之前必须设置4-5个属性,否则我们将冻结对象创建直到尚未设置某些属性。 基本上,使用它代替构造函数-正如Joshua Bloch在Effective Java,2nd Edition中指出的那样。 构建器公开了生成的对象应具有的属性,但隐藏了如何设置它们。

装饰器用于添加现有对象的新功能以创建新对象。 在添加对象的所有功能之前,没有冻结对象的限制。 两者都使用合成,因此它们看起来可能相似,但是在用例和意图上有很大不同。

另一种方法是使用工厂模式。 如果我们不想公开这些属性,而是希望“神奇地”在内部创建某些披萨,则可以基于某些属性。 我们将在以后的文章中使用Factory Pattern探索该实现。

翻译自: https://www.javacodegeeks.com/2014/08/pizza-problem-builder-vs-decorator.html

分披萨问题

分披萨问题_比萨问题–建造者与装饰者相关推荐

  1. 分披萨问题_比萨疯狂问题

    分披萨问题 Problem statement: 问题陈述: There is a shop which sells pizza of three different sizes- Small, Me ...

  2. 披萨店小程序_比萨问题–建造者与装饰者

    披萨店小程序 问题陈述 我们需要为一家披萨公司构建软件,该公司想要准备不同类型的披萨,例如鸡肉披萨,扁平面包,意大利辣香肠披萨和额外的奶酪,并在上面放些配料. 让我们尝试看看哪种设计模式适合该问题说明 ...

  3. 比萨问题–建造者与装饰者

    问题陈述 我们需要为一家披萨公司构建软件,该公司想要准备各种类型的披萨,例如鸡肉披萨,扁平面包,意大利辣香肠披萨和额外的奶酪,并在上面放些配料. 让我们尝试看看哪种设计模式适合该问题说明以及在哪种情况 ...

  4. 计算机考研340分什么概念,考研340分什么概念_中国考研网官网入口

    考研340分什么概念_中国考研网官网入口由广东研究生考试网考试快讯栏目由提供,更多关于考研340分什么概念,中国考研网官网入口,广东研究生考试快讯的内容,请关注广东研究生考试频道/广东人事考试网! 从 ...

  5. 2016计算机考研330分,考研330分什么概念_中国研究生招生信息网官方

    考研330分什么概念_中国研究生招生信息网官方由广东研究生考试网考试快讯栏目由提供,更多关于考研330分什么概念,中国研究生招生信息网官方,广东研究生考试快讯的内容,请关注广东研究生考试频道/广东人事 ...

  6. 考研计算机350分相当于什么水平,考研350分什么水平_中国研究生招生信息网登录...

    考研350分什么水平_中国研究生招生信息网登录由广东研究生考试网考试快讯栏目由提供,更多关于考研350分什么水平,中国研究生招生信息网登录,广东研究生考试快讯的内容,请关注广东研究生考试频道/广东人事 ...

  7. 分库分表之_分库分表 + 复杂查询

    前言 Github:https://github.com/HealerJean 博客:http://blog.healerjean.com 代码配置暂时和和分库分表之_分库分表相同.但是为了测试下面的 ...

  8. POJ 3122 分披萨(二分查找)

    题目链接:http://poj.org/problem?id=3122 题目大意: 有 n 块披萨(大小不一样), f 个人分,包含主人自己 f+1 人: 每人吃的披萨必须是一块披萨上切下来的.每个人 ...

  9. mysql分表插件_分库分表简单?那我想问如何实现“分库分表插件”?

    随着系统数据量的日益增长,在说起数据库架构和数据库优化的时候,我们难免会常常听到分库分表这样的名词. 当然,分库分表有很多的方法论,比如垂直拆分.水平拆分:也有很多的中间件产品,比如MyCat.Sha ...

最新文章

  1. linux如何取文件列名,Linux ps 指定列名
  2. python如何查询数据库_Python数据库操作手册-数据库专栏,SQL Server
  3. 计算机负责指令代码的是,计算机组成原理习题2新版资料.doc
  4. Django 【认证系统】auth
  5. django设置超级管理员_Django的简介与安装
  6. 这张父子照曾火遍全国,如今他们的故事比照片更动人
  7. Bailian2786 Pell数列【数列】(POJ NOI0102-1788,POJ NOI0103-1788)
  8. CrystalReports水晶报表开发中遇到的问题
  9. paper - A Physics-based Noise Formation Model for Extreme Low-light Raw Denoising
  10. 硬件加速 setlayertype
  11. 【NTL密码算法开源库-概述】
  12. CNN神经网络猫狗分类经典案例,深度学习过程中间层激活特征图可视化
  13. https 以及内网如何使用
  14. 游戏后台之内存管理篇
  15. 发运确认后,订单行保持“已挑库”状态 Order Line Remains in Picked (Awaiting Shipping) Status After Ship Confirmation
  16. 天池- IJCAI-18 阿里妈妈搜索广告转化预测新手入门经历(一:数据预处理、特征工程)
  17. android 自定义 对号,Android 自定义View 对勾CheckBox
  18. 循序渐进全球化 镜像识别
  19. RS|下载RapidEye(5m分辨率)/Planetscope (3m)的网站申请流程(planet.com)
  20. 我的黑群晖学习之旅(4)外网访问之ZeroTier

热门文章

  1. 2018/7/9-纪中某B组题【jzoj1503,jzoj1158,jzoj1161】
  2. P2055-假期的宿舍【网络流,最大流,最大匹配】
  3. 【随机】Ghd(CF364D)
  4. JFreeChart(一)之架构
  5. Jsoup代码解读之四-parser(上)
  6. Java GC系列(2):Java垃圾回收是如何工作的
  7. 使用Java 8 Stream像操作SQL一样处理数据(上)
  8. 使用相对长度单位em布局网页内容
  9. PhotoShop基础知识
  10. Servlet使用适配器模式进行增删改查案例(BaseDaoUtilImpl.java)