分披萨问题_比萨问题–建造者与装饰者

分披萨问题

问题陈述

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

让我们尝试看看哪种设计模式适合该问题说明以及在哪种情况下。 传统上,对于披萨问题,最常用的是构造器模式。 但是,也有一些使用装饰器的示例,两种方法都是正确的,但用例有所不同。 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

分披萨问题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/339999.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用python随机生成5000个网址_使用Python脚本生成随机IP的简单方法

需求在某应用中,需要根据一定的规则生成随机的IP地址,规则类似于192.168.11.0/24这样的CIDR形式给出。实现经过艰苦卓绝的调试,下面的代码是可以用的:RANDOM_IP_POOL[192.168.10.222/0]def __get_random_ip():str_ip RANDOM_IP_P…

linux应用程序安装PPT免费序,linux下应用程序安装的总结

linux下应用程序安装的总结上一篇 / 下一篇 2009-04-20 14:45:37 / 个人分类:技术我解查看( 203 ) / 评论( 0 ) / 评分( 0 / 0 )一、常用的Linux应用软件的安装包有2种:1. tar包,如software-1.2.3-1.tar.gz。它是使用linux系统的打包工具tar打…

Quarkus入门

Quarkus – 一个为OpenJDK HotSpot和GraalVM量身定制的Kubernetes本机Java堆栈,它是从最佳Java库和标准中精制而成的。 –是一个容器优先的框架,针对快速启动时间和低内存消耗进行了优化。 该框架基于许多流行的Java库构建,并且为构建标准RES…

vmware6.5.2序列号_教你如何查询苹果序列号,查询是否为官换机、激活时间等

如何查询你刚买的苹果设备是否为官换机?或想知道它的激活日期?保修时间?那么赶紧收藏本篇教程吧!众所周知,在苹果官网查询苹果设备,是查询不到具体的信息(比如激活日期、保修日期、是否为官换机…

linux 几个文件夹作用,linux下每一个文件夹的作用.docx

目录结构及主要内容“/"根冃录部分有以F子冃录:/usr 口录包含所有的命令、程序库、文档和英它文件。这些文件在正常操作中不会被改变的。这个目录也包含你的Linux 发行版本的主要的应用程序,辔如,Netscape0/var目录包含在1E常操作中被改…

参数化测试 junit_JUnit中的参数化测试运行器

参数化测试 junit我们都有书面的单元测试,其中在一个测试中针对不同的可能的输入输出组合进行测试。 让我们以一个简单的斐波那契数列示例为例,看看它是如何完成的。 以下代码针对提到的元素数量计算斐波那契数列: import java.math.BigInt…

python中dataframe合并列名日期到季度_python – 如何在特定日期范围内的pandas列DataFrame中对某些值求和...

我有一个大型的DataFrame,看起来像这样:df UPC Unit_Sales Price Price_Change Date0 22 15 1.99 NaN 2017-10-101 22 7 2.19 True 2017-10-122 22 6 2.19 NaN 2017-10-133 22 7 1.99 True 2017-10-164 22 4 1.99 NaN 2017-10-175 35 15 3.99 NaN 2017-10-096 35 17…

linux环境变量自动配置,Linux进入系统时自动配置 环境变量的要领

用Export命令能够配置环境变量,但是假如每回进入系统之后都要重新配置一遍环境变量就很烦人。Linux给大众提供了自动配置环境变量的要领,那就是修改.bashrc 文件。 通常说来,有两个文件能够提供这种“进入系统时自动配置”的功能,…

金融模型python_盘点金融领域里常用的深度学习模型

作者 | Sonam Srivastava ,译者 | sambodhi ,编辑 | Vincent ,AI前线出品| ID:ai-front在今天我们发布的这篇文章中,作者 Sonam Srivastava 介绍了金融中的三种深度学习用例及这些模型优劣的证据。我们跟随…

Qute模板与Quarkus

Quarkus附带了自己的模板引擎Qute,该引擎已经包含了一组有趣的功能。 在下面的视频中,我将展示基于动作的MVC与JAX-RS的基本用法,该动作将我们的请求转发到HTML模板。 要自己尝试Qute,请查看以下资源: 示例项目 Qut…

linux 7启动文件夹在哪里设置密码,RHEL7 or CentOS7 的系统密码如何重置

导读RHEL7 的世界发生了变化,重置 root 密码的方式也一样。虽然中断引导过程的旧方法(init/bin/bash)仍然有效,但它不再是推荐的。“Systemd” 使用 “rd.break” 来中断引导。让我们快速浏览下整个过程。介绍目的在 RHEL7/CentOS7/Scientific Linux 7 中…

里氏替换原则_代码需要有单一职责,还要开闭,里氏替换又是什么鬼?

目录单一职责原则:开闭原则:里氏替换原则:单一职责原则:每一个系统中的功能都表示一个职责,这些职责可以映射到模块(类)中,且尽可能的保证这些类中没有功能上的重复,设计…

linux bind日志级别,BIND日志相关(一)

对于排除DNS故障来说,日志文件是极其重要的工具,DNS日志可以记录服务器CPU占用时间,查询统计信息以及配置中存在的问题。经常分析日志可以了解服务器的负荷,性能安全性,从而及时采取措施纠正错误。BIND在默认情况下&am…

junit:junit_简而言之,JUnit:测试结构

junit:junit尽管存在有关JUnit测试的书籍和文章,但我仍然经常遇到程序员,他们至多对这个工具及其正确用法都不甚了解。 因此,我想到了编写多部分教程的想法,从我的角度解释了要点。 也许在本微型系列文章中采用的动手方法可能适合…

联想打印机7256显示更换墨盒_惠普打印机涉嫌垄断?只认自家“昂贵”墨盒,成本太高招架不住...

近日,有人爆料称,所在公司购买的惠普打印机使用原装墨盒时可正常打印,更换其他品牌墨盒后也不能正常使用,因此认为惠普公司有行业垄断的嫌疑。从细节来看,该公司购买了惠普同一型号但不同批次的两台打印机,…

linux mcelog 运行,服务器硬件检测(采用mcelog)

mt 内存监控:mcecheck.pyraid监控: check-raidmcelog 是 x86 的 Linux 系统上用来检查硬件错误,特别是内存和CPU错误的工具。安装方式yum install mcelog运行mcelog查看日志方式/var/log/mcelogMCE 0HARDWARE ERROR. This is NOT a software …

动手选择值

由于冠状病毒的存在,可选的东西在空中,一切都变得可选,例如可选的公共聚会,可选的在家工作,可选的旅行等。 我现在是时候谈论处理NULL引用的软件工程中真正的“ 可选 ”了。 托尼霍尔(Tony Hoare&#xf…

python mysql操作_Python的MySQL操作

Python的DB-API,为大多数的数据库实现了接口,使用它连接各数据库后,就可以用相同的方式操作各数据库。Python DB-API使用流程:引入API模块。获取与数据库的连接。执行SQL语句和存储过程。关闭数据库连接。一、安装MySQL客户端MySQLdb 是用于Python链接Mysql数据库的接口&#x…

linux下的遥控器软件下载,Linux操作系统下遥控器的配置及使用方法

你有没有想象过能够坐在沙发上,或者躺在床上,拿着遥控器像操作电视一样来操作电脑?可能你已经见到过市场上出现的那种电脑遥控器,不过它们都是基于windows下的。其实,通过一定的配置,在linux平台上&#xf…

wincc历史数据库_WinCC系统的基本功能介绍——自动化工程师必备

写在面前前面讲解了西门子的TIA Portal Wincc, Wincc Classic和Wincc OA (一文带你了解西门子Wincc),介绍了西门子的超大型/分布式SCADA系统Wincc OA(初识西门子Wincc OA——超大型/分布式SCADA),还介绍了Wincc Classic的典型架构和选型指南(WinCC V7.5典型架构及选…