建造者模式:使用多个简单对象一步步构建成一个复杂的对象。

有时候,我们会创建一个“复杂”的对象,这个对象的由很多子对象构成,由于需求的变化,这个对象的各个部分经常面临剧烈的变化。

继续工厂模式的披萨店案例,现在披萨店要推出套餐服务,一个套餐(Meal)包含:披萨、饮料,披萨可以是芝士披萨(Cheese Pizza)、素食披萨(Veggie Pizza)等,披萨是包在盒子(Box)里,饮料可以是可口可乐(Coke)、橙汁(Orange)等,饮料装在杯子(Cup)里。

我们将创建一个表示食物的条目(包括披萨和饮料)的Item接口和实现Item接口的实体类(Pizza和Drink),以及一个表示装食物容器的Packing接口和实现Packing接口的实体类(Box和Cup),然后创建一个Meal类,该类有一个Item类型的ArrayList来放入套餐,以及一个MealBuilder来提供不同套餐。

Item.java

public interface Item {
public String name();
public Packing packing();
public float price();
}

Packing.java

public interface Packing {
public String pack();
}

Box实现Packing容器接口

public class Box implement Packing {
public String pack() {
return "Box";
}
}

Cup同样实现Packing容器接口

 public class Cup implements Packing {
public String pack() {
return "Bottle";
}
}

Pizza实现Item接口,声明为抽象类,因为有不同种类的Pizza

public abstract class Pizza implements Item {
public Packing packing() {
return new Box();
}
  public abstract float price();
}

Drink实现Item接口,声明为抽象类,因为有不同种类的Drink

public abstract class Drink implements Item {
public Packing packing() {
return new Cup();
}
public abstract float price();
}

CheesePizza.java,Veggie就不写了,跟CheesePizza一样

public CheesePizza extends Pizza {
public float price() {
return 20.0f;
}
public String name() {
return "Cheese Pizza";
}
}

Coke.java,Orange就不写了,跟Coke一样

public class Coke extends Drink {
public float price() {
return 7.0f;
}
public String name() {
return "Coke";
}
}

Meal.java

public class Meal {
private List<Item> items = new ArrayList<Item>(); public void addItem(Item item) {
items.add(item);
} public float getCost() {
float cost = 0.0f;
for(Item item : items) {
cost += item.price();
}
return cost;
} public void showItems() {
for(Item item : items) {
System.out.print("Item :" + item.name());
System.out.print(",Packing : :" + item.packing());
System.out.println(",Price :" + item.price());
}
System.out.printlln("Total cost :" + this.getCost());
}
}

MealBuilder.java负责创建Meal对象

public class MealBuilder {

    public Meal prepareCheesePizza() {
Meal meal = new Meal();
meal.addItem(new CheesePizza());
meal.addItem(new Coke());
return meal;
} public Meal prepareVeggiePizza() {
Meal meal = new Meal();
meal.addItem(new VeggiePizza());
meal.addItem(new Orange());
return meal;
}
}

工作已经完成,可以使用MealBuilder了

public static void main(String[] args) {
MealBuilder mb = new MealBuilder(); Meal cheesePizza = mealBuilder.prepareCheesePizza();
System.out.println("Cheese Pizza");
cheesePizza.showItem(); Meal veggiePizza = mealBuilder.prepareVeggiePizza();
veggiePizza.showItem();
}

建造者模式(Builder Pattern)的更多相关文章

  1. 【原】iOS设计模式之:建造者模式Builder Pattern,用于改进初始化参数

    本文主要讨论一下iOS中的Builder Pattern.与网上很多版本不同,本文不去长篇大论地解释建造者模式的概念,那些东西太虚了.设计模式这种东西是为了解决实际问题的,不能为了设计模式而设计模式, ...

  2. 乐在其中设计模式(C#) - 建造者模式(Builder Pattern)

    原文:乐在其中设计模式(C#) - 建造者模式(Builder Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 建造者模式(Builder Pattern) 作者:webabc ...

  3. 【设计模式】建造者模式 Builder Pattern

    前面学习了简单工厂模式,工厂方法模式以及抽象工厂模式,这些都是创建类的对象所使用的一些常用的方法和套路, 那么如果我们创建一个很复杂的对象可上面的三种方法都不太适合,那么“专业的事交给专业人去做”,2 ...

  4. 建造者模式(Builder Pattern)

    建造者模式(Builder Pattern) 它可以将多个简单的对象一步一步构建成一个复杂的对象. 意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示. 主要解决:主要解决在软 ...

  5. 二十四种设计模式:建造者模式(Builder Pattern)

    建造者模式(Builder Pattern) 介绍将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 示例用同样的构建过程创建Sql和Xml的Insert()方法和Get()方 ...

  6. iOS设计模式之:建造者模式Builder Pattern,用于改进初始化参数

    转自:http://www.cnblogs.com/wengzilin/p/4365855.html 本文主要讨论一下iOS中的Builder Pattern.与网上很多版本不同,本文不去长篇大论地解 ...

  7. 设计模式系列之建造者模式(Builder Pattern)——复杂对象的组装与创建

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

  8. Net设计模式实例之建造者模式(Builder Pattern)

    一.建造者模式简介(Brief Introduction) 建造者模式(Builder Pattern),将一个复杂对象的构建与它的表示分离,使的同样的构建过程可以创建不同的表示. 建造者模式的优点是 ...

  9. Python 设计模式之建造者模式 Builder Pattern

    #引入建造者模式 肯德基的菜单上有 薯条, 鸡腿,鸡翅,鸡米花,可乐,橙汁,火腿汉堡,至尊虾汉堡,牛肉汉堡 , 鸡肉卷等这些单品,也有很多套餐. 比如 套餐1:鸡翅,至尊虾汉堡,可乐,薯条 套餐2:鸡 ...

  10. 设计模式 - 建造者模式 Builder Pattern

    简介 场景 在创建复杂对象时,用户无须关心该对象所包含的属性以及它们的组装方式,只需要指定复杂对象的类型和内容就可以构建它们. 模式定义 建造者模式:将一个复杂对象的构建与表示分离,使得同样的构建过程 ...

随机推荐

  1. IDF实验室-简单编程-特殊的日子 writeup

    题目:http://ctf.idf.cn/index.php?g=game&m=article&a=index&id=50 题目提示要爆破,代表加密应该是不可逆的. 密文:4D ...

  2. Abel 分部求和法

    本文之所以叫Abel分部求和法而不叫Abel分部求和公式,是因为求和公式有可能形式上有所不同,但是方法确实相同的. $$\sum_{n=M}^{N}a_{n}b_{n} = \sum_{n=M}^{N ...

  3. 9 个让 JavaScript 调试更简单的 Console 命令

    一.显示信息的命令 <!DOCTYPE html> <html> <head> <title>常用console命令</title> < ...

  4. Redis实战之Redis + Jedis

    用Memcached,对于缓存对象大小有要求,单个对象不得大于1MB,且不支持复杂的数据类型,譬如SET 等.基于这些限制,有必要考虑Redis! 相关链接: Redis实战 Redis实战之Redi ...

  5. ListView Video

    com.baidu.frontia.FrontiaApplication ListView Video <item name="android:windowBackground&quo ...

  6. [Python]linux自己定义Python脚本命令

    在window下写好的程序配置到Linux上,要实现随意文件夹下的命令调用. 因为初学Linux,这里从文件传输等最主要的方法入手,记录配置的过程中遇到的各种问题. 连接远端server 这里使用pu ...

  7. java_jdbc_可变参数_MetaData

    异常处理参考3层解耦 ublic class ScrollTest { public static void main(String[] args) throws SQLException { // ...

  8. javascript笔记07:使用Object类为实例定义方法和属性

    function Person() {} Person.prototype = { nickName:"john", , showInfo:function() { return ...

  9. 读取Log日志并打印到sdcard

    @SuppressLint("SimpleDateFormat") private static SimpleDateFormat sdf = new SimpleDateForm ...

  10. Hibernate学习笔记--------4.查询

    一.Get/Load Get方法是立即检索,而load是延迟检索,他们都是根据主键进行查询.在<class>标签中,若把lazy属性改为false,load方法就会立即检索,class中的 ...