【秒懂设计模式】建造者模式

简介:  秒懂设计模式——建造者模式 (四)建造者模式 1.先解释一下,什么是建造者模式呢? 【官方定义】将一个复杂对象的构建,与它的表示分离,使得同样的构建过程可以创建不同的表示。 【理解】官方定义过于抽象,让我们把它做一个拆分,分解成四个方面理解: ①复杂对象的表示; ②复杂对象的构建过程; ③可分离的通用构建过程,也适用于其它复杂对象的表示; ④适用于一些基本部件不会变,

 秒懂设计模式——建造者模式


(四)建造者模式

1.先解释一下,什么是建造者模式呢?

【官方定义】将一个复杂对象的构建,与它的表示分离,使得同样的构建过程可以创建不同的表示。

【理解】官方定义过于抽象,让我们把它做一个拆分,分解成四个方面理解

①复杂对象的表示;

②复杂对象的构建过程;

③可分离的通用构建过程,也适用于其它复杂对象的表示;

④适用于一些基本部件不会变,而其组合经常变化的时候。

2.接着,让我们再伴随一个例子,进一步清晰的理解这个定义:

【举例】常去KFC的朋友,一般都会发现,其实它的很多食品组合都能构成套餐,但是它们的包装组合却很少变动,比如:“[盒装]香辣汉堡+[杯装]可乐”是一个套餐;再比如:“[盒装]奥尔良烤腿堡+[杯装]雪顶咖啡”也是一个套餐。

3.我们按照上面所说的4个方面,从建造者的设计角度,分析一下这个例子:

①复杂对象的表示KFC套餐

②复杂对象的构建过程盒装+杯装

③可分离的通用构建过程,也适用于其它复杂对象的表示不同的包装可以放不同的食物

④适用于一些基本部件不会变包装组合不变),而其组合经常变化的时候包装内的食品组合经常变化)。

4.我们准备用Java代码来,以建造者模式来实现这一下这个例子。

Java代码】

①创建食品抽象接口

package com.liyan.builderpattern;
/**
 * 食品抽象产品接口类
 * <p>Title: FoodModel</p>  
 * @author  Liyan  
 * @date    2017年4月28日 下午2:02:21
 */
public interface FoodInterface {
	/**食品名字*/
	public String name();
	/**食品包装*/
	public String packing();
	/**食品价格*/
	public Double price();
}

②创建食品包装抽象接口

package com.liyan.builderpattern;
/**
 * 食品包装类接口
 * <p>Title: PackingInterface</p>  
 * @author  Liyan  
 * @date    2017年4月28日 下午2:06:40
 */
public interface PackingInterface {
	public String pack();
}

③创建汉堡抽象类,并实现食品接口,并重写食品包装方法

package com.liyan.builderpattern;
/**
 * 汉堡抽象类
 * <p>Title: Burger</p>  
 * @author  Liyan  
 * @date    2017年4月28日 下午2:19:39
 */
public abstract class Burger implements FoodInterface {
	@Override
	//名称抽象方法
	public abstract String name();
	@Override
	//包装方法
	public String packing() {
		//汉堡用纸盒包装
		return new BoxPacking().pack();
	}
	@Override
	//价格抽象方法
	public abstract Double price();
}

创建饮料抽象类,并实现食品接口,并重写食品包装方法

package com.liyan.builderpattern;
/**
 * 饮料抽象类
 * <p>Title: Coke</p>  
 * @author  Liyan  
 * @date    2017年4月28日 下午3:14:12
 */
public abstract class Drinking implements FoodInterface{
	@Override
	//名称抽象方法
	public abstract String name();
	@Override
	//包装方法
	public String packing() {
		//饮料用杯装
		return new CupPacking().pack();
	}
	@Override
	//价格抽象方法
	public abstract Double price();
}

④创建香辣鸡腿堡具体产品类,并继汉堡类创建饮料抽象类,并实现食品接口,并重写食品包装方法

package com.liyan.builderpattern;
/**
 * 香辣鸡腿堡具体产品类
 * <p>Title: SpicyChickenBurger</p>  
 * @author  Liyan  
 * @date    2017年4月28日 下午3:39:27
 */
public class SpicyChickenBurger extends Burger {
	@Override
	public String name() {
		return "香辣鸡腿堡";
	}
	@Override
	public Double price() {
		return 16.5;
	}
}

创建奥尔良烤腿堡具体产品类,并继汉堡类

package com.liyan.builderpattern;
/**
 * 奥尔良烤腿堡具体产品类
 * <p>Title: SpicyChickenBurger</p>  
 * @author  Liyan  
 * @date    2017年4月28日 下午3:39:27
 */
public class FortRoastedLegOrleans extends Burger {
	@Override
	public String name() {
		return "奥尔良烤腿堡";
	}
	@Override
	public Double price() {
		return 18.5;
	}
}

⑤创建可口可乐具体产品类,并继承饮料类

package com.liyan.builderpattern;
/**
 * 可口可乐具体产品类
 * <p>Title: CocaCola</p>  
 * @author  Liyan  
 * @date    2017年4月28日 下午3:46:57
 */
public class CocaCola extends Drinking {

	@Override
	public String name() {
		return "中杯可口可乐";
	}

	@Override
	public Double price() {
		return 8.5;
	}

}

创建雪顶咖啡具体产品类,并继承饮料类

package com.liyan.builderpattern;
/**
 * 雪顶咖啡具体产品类
 * <p>Title: IcyTopCoffe</p>  
 * @author  Liyan  
 * @date    2017年4月28日 下午3:48:15
 */
public class IcyTopCoffe extends Drinking {
	@Override
	public String name() {
		return "雪顶咖啡";
	}
	@Override
	public Double price() {
		return 9.5;
	}
}

⑥创建套餐的过程

package com.liyan.builderpattern;
import java.util.ArrayList;
import java.util.List;
/**
 * 套餐的创建过程
 * <p>
 * Title: Package
 * </p>
 * 
 * @author Liyan
 * @date 2017年4月28日 下午4:08:20
 */
public class Package {

	//套餐内的食品集合
	private List<FoodInterface> foods = new ArrayList<FoodInterface>();
	
    /**
	 * 添加食物
	 * <p>Title: addFood</p>  
	 * @author Liyan  
	 * @date   2017年4月28日 下午4:12:59  
	 * @param food 食物  
	 */
	public void addFood(FoodInterface food) {
		foods.add(food);
	}

	/**
	 * 计算价格
	 * <p>Title: getCost</p>  
	 * @author Liyan  
	 * @date   2017年4月28日 下午4:14:59  
	 * @return float 总价
	 */
	public float getCost() {
		float cost = 0.0f;
		for (FoodInterface item : foods) {
			cost += item.price();
		}
		return cost;
	}

	/**
	 * 展示套餐清单
	 * <p>Title: showFoods</p>  
	 * @author Liyan  
	 * @date   2017年4月28日 下午4:15:23        
	 */
	public void showFoods() {
		for (FoodInterface food : foods) {
			System.out.print("食物名称 : " + food.name());
			System.out.print(", 包装 : " + food.packing());
			System.out.println(", 价格 : " + food.price());
		}
	}
}

⑦实际套餐的创建者

package com.liyan.builderpattern;
/**
 * 实际套餐的创建者
 * <p>Title: PackageBuilder</p>
 * @author Liyan
 * @date 2017年4月28日 下午4:17:17
 */
public class PackageBuilder {
	/**
	 * 创建套餐一:香辣鸡腿堡+可乐
	 * <p>Title: package1</p>  
	 * @author Liyan  
	 * @date   2017年4月28日 下午4:20:22  
	 * @return Package
	 */
	public Package package1() {
		Package package1 = new Package();
		package1.addFood(new SpicyChickenBurger());
		package1.addFood(new CocaCola());
		return package1;
	}
	/**
	 * 创建套餐二:奥尔良烤腿堡+雪顶咖啡
	 * <p>Title: package2</p>  
	 * @author Liyan  
	 * @date   2017年4月28日 下午4:21:14  
	 * @return Package
	 */
	public Package package2() {
		Package package2 = new Package();
		package2.addFood(new FortRoastedLegOrleans());
		package2.addFood(new IcyTopCoffe());
		return package2;
	}
	/**
	 * 创建套餐三:香辣鸡腿堡+雪顶咖啡
	 * <p>Title: package3</p>  
	 * @author Liyan  
	 * @date   2017年4月28日 下午4:22:04  
	 * @return Package
	 */
	public Package package3() {
		Package package3 = new Package();
		package3.addFood(new SpicyChickenBurger());
		package3.addFood(new IcyTopCoffe());
		return package3;
	}
	/**
	 * 创建套餐四:奥尔良烤腿堡+可乐
	 * <p>Title: package4</p>  
	 * @author Liyan  
	 * @date   2017年4月28日 下午4:23:19  
	 * @return Package
	 */
	public Package package4() {
		Package package4 = new Package();
		package4.addFood(new FortRoastedLegOrleans());
		package4.addFood(new CocaCola());
		return package4;
	}
}

⑧顾客登场,开始点餐

package com.liyan.builderpattern;
/**
 * 顾客开始点餐
 * <p>Title: Customer</p>  
 * @author  Liyan  
 * @date    2017年4月28日 下午4:33:00
 */
public class Customer {
	
	public static void main(String[] args) {
		PackageBuilder packageBuilder = new PackageBuilder();

		System.out.println("我是套餐一================");
		Package package1 = packageBuilder.package1();
		package1.showFoods();
		
		System.out.println("我是套餐二================");
		Package package2 = packageBuilder.package2();
		package2.showFoods();
		
		System.out.println("我是套餐三================");
		Package package3 = packageBuilder.package3();
		package3.showFoods();
		
		System.out.println("我是套餐四================");
		Package package4 = packageBuilder.package4();
		package4.showFoods();    
	}
}

⑨控制台输出结果

我是套餐一================
食物名称 : 香辣鸡腿堡, 包装 : 纸盒包装, 价格 : 16.5
食物名称 : 中杯可口可乐, 包装 : 杯装, 价格 : 8.5
我是套餐二================
食物名称 : 奥尔良烤腿堡, 包装 : 纸盒包装, 价格 : 18.5
食物名称 : 雪顶咖啡, 包装 : 杯装, 价格 : 9.5
我是套餐三================
食物名称 : 香辣鸡腿堡, 包装 : 纸盒包装, 价格 : 16.5
食物名称 : 雪顶咖啡, 包装 : 杯装, 价格 : 9.5
我是套餐四================
食物名称 : 奥尔良烤腿堡, 包装 : 纸盒包装, 价格 : 18.5
食物名称 : 中杯可口可乐, 包装 : 杯装, 价格 : 8.5

5.分析:以上就是建造者模式的Java实现过程,下面用画图的方式,梳理一下各种关系:

 

我们发现建造者模式有四个角色

Builder:给出一个抽象接口,以规范产品对象的各个组成成分的建造。这个接口规定要实现复杂对象的哪些部分的创建,并不涉及具体的对象部件的创建。(食品抽象接口

ConcreteBuilder:实现Builder接口,针对不同的商业逻辑,具体化复杂对象的各部分的创建。 在建造过程完成后,提供产品的实例。(包装抽象接口

Product:要创建的复杂对象。(套餐类

Director:调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建。(实际套餐的建造者类

 

相关文章
|
6月前
|
设计模式 Java
【设计模式系列笔记】建造者模式
建造者模式是一种创建型设计模式,用于将复杂对象的构建与其表示分离,使构建过程可定制。关键元素包括产品类(定义要构建的对象)、建造者接口(定义构建方法)、具体建造者类(实现构建过程)和指导者类(负责构建过程)。通过建造者模式,客户端可以灵活地创建具有不同表示的复杂对象,提高代码的可读性和可维护性,尤其适用于构建过程复杂且包含多个可选部分的情况。
132 1
|
6月前
|
设计模式 安全 Java
构建未来应用:Java设计模式 - 建造者模式(Builder)在现代编程中的应用
【4月更文挑战第7天】建造者模式是提升代码质量的关键,尤其在复杂环境中。它分步骤构建对象,将构建与表示分离,适用于UI构建、数据模型组装、配置文件解析和网络请求构造等场景。最佳实践包括明确构建步骤、提供默认值、支持链式调用和确保线程安全。然而,过多步骤、不一致状态和性能问题是使用时需注意的问题。掌握建造者模式对于现代编程至关重要。
86 3
|
2月前
|
设计模式 算法
设计模式--建造者模式 builder
这篇文章通过一个电脑购买的例子,详细解释了建造者模式的四个角色(产品类、抽象构建者、实体构建类和指导者类),并提供了相应的代码实现,阐述了建造者模式在设计复杂对象时的应用和优势。
设计模式--建造者模式 builder
|
11天前
|
设计模式 JavaScript Java
Java设计模式:建造者模式详解
建造者模式是一种创建型设计模式,通过将复杂对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。本文详细介绍了建造者模式的原理、背景、应用场景及实际Demo,帮助读者更好地理解和应用这一模式。
|
2月前
|
设计模式 算法 Java
Java设计模式-建造者模式(6)
Java设计模式-建造者模式(6)
|
3月前
|
设计模式 XML 存储
【四】设计模式~~~创建型模式~~~建造者模式(Java)
文章详细介绍了建造者模式(Builder Pattern),这是一种创建型设计模式,用于将复杂对象的构建与其表示分离,允许分步骤创建一个复杂的对象而无需指定其内部的具体构造细节。通过定义抽象建造者、具体建造者、指挥者和产品角色,建造者模式允许通过相同的构建过程创建不同的产品表示,提高了系统的灵活性和扩展性。
|
5月前
|
设计模式 算法
建造者模式-大话设计模式
建造者模式-大话设计模式
|
6月前
|
设计模式 uml
大话设计模式(3)——造物者一般的建造者模式
大话设计模式(3)——造物者一般的建造者模式
43 1
大话设计模式(3)——造物者一般的建造者模式
|
4月前
|
设计模式 JavaScript
js设计模式【详解】—— 建造者模式
js设计模式【详解】—— 建造者模式
55 0
|
5月前
|
设计模式
设计模式-05建造者模式(Builder Pattern)
设计模式-05建造者模式(Builder Pattern)

热门文章

最新文章

  • 1
    C++一分钟之-设计模式:工厂模式与抽象工厂
    43
  • 2
    《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
    50
  • 3
    C++一分钟之-C++中的设计模式:单例模式
    58
  • 4
    《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
    38
  • 5
    《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
    64
  • 6
    Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
    59
  • 7
    Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
    42
  • 8
    Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
    50
  • 9
    Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
    112
  • 10
    Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
    78