23种设计模式——建造者模式

目录

建造者模式

UML图

示例代码

适用场景

优缺点

建造者模式VS工厂模式 :

实例


建造者模式

本质: 分离整体构建算法和部件构造

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

创建过程是稳定的

UML图

过程:客户把具体建造者对象交给指导者,指导者操纵具体建造者创建产品。产品创建完成后,具体建造者把产品返还给客户端

在这里插入图片描述

建造者(Builder)角色:

定义创建一个Product对象所需各个操作的方法+一个返回Product对象的方法

具体建造者(Concrete Builder)角色:

实现Builder中的方法,完成创建产品实例的过程+提供产品的实例

指导者(Director)角色:(核心)

使用Builder中的方法,以一个统一的过程来构建所需要的Product对象

产品(Product)角色:

需要建造的复杂对象。

客户端:

创建指导者和具体建造者的对象。

示例代码

public class Director {
	public void Construct(Builder builder){
		builder.BuildPartA();
		builder.BuildPartB();
	}
}
public abstract class Builder {
	//产品由两个组件A、B组成(A、B是抽象的,还不确定)
	public abstract void BuildPartA();
	public abstract void BuildPartB();
	//得到产品建造结果
	public abstract Product getResult();

}
public class ConcreteBuilder1 extends Builder{
	private Product product=new Product();

	@Override
	public void BuildPartA() {
		System.out.println("部件a");
	}

	@Override
	public void BuildPartB() {
		System.out.println("部件b");
	}

	@Override
	public Product getResult() {
		return product;
	}

}
public class ConcreteBuilder2 extends Builder{
	private Product product=new Product();

	@Override
	public void BuildPartA() {
		System.out.println("部件X");
	}

	@Override
	public void BuildPartB() {
		System.out.println("部件Y");
	}

	@Override
	public Product getResult() {
		return product;
	}

}
import java.util.ArrayList;

public class Product {
	ArrayList<String> parts=new ArrayList<String>();
	
	public void Add(String part){
		parts.add(part);
	}
	
	public void show(){
		System.out.println("产品创建");
		for(String part:parts){
			System.out.println(part);
		}
	}

}
public class Main {

	public static void main(String[] args) {
		Director director=new Director();
		Builder b1=new ConcreteBuilder1();
		Builder b2=new ConcreteBuilder2();
		
		director.Construct(b1);
		Product p1=b1.getResult();
		p1.show();
		
		director.Construct(b2);
		Product p2=b2.getResult();
		p2.show();
	}

}

适用场景

  • 需要生成的产品对象有复杂的内部结构。
  • 需要生成的产品对象的属性相互依赖,建造者模式可以强迫指定其生成顺序。
  • 在对象创建过程中会使用到系统中的一些其它对象,这些对象在产品对象的创建过程中不易得到。

优缺点

优点:

  • 产品的内部组成可独立的变化
  • 客户端不必知道产品内部组成的细节
  • 扩展性好:具体建造类相互独立
  • 将复杂的产品创建过程分解,更方便控制创建过程

缺点:

  • 适用范围受限:要求创建的产品具有较多的共同点,其组成部分相似。如果产品之间的差异性很大,如组成部分很多不同,则不适合用建造者模式。

  • 如果产品内部变化复杂,可能需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大,增加了系统的理解难度和运行成本

建造者模式VS工厂方法模式 :

  • 注重点不同:建造者模式注重于方法的调用顺序;工厂模式注重创建产品对象
  • 创建对象力度不同:建造者模式可以创建复杂的产品;工厂模式创建出来的都是相同的实例对象。
     

实例——导出文件

导出数据的应用框架,通常对于具体的导出内容和格式是有要求的:

分成三部分,文件头、文件体、文件尾

  • 文件头:分公司编号、导出数据的日期,对于文本格式,中间用逗号分离
  • 文件体:表名称,然后分条描述数据
  • 文件尾:输出人

不管是输出文本文件,还是输出XML文件,步骤基本一致

  • 先拼接文件头的内容
  • 然后拼接文件体的内容
  • 再拼接文件尾的内容

最后把拼接好的内容输出去成为文件

public class Director {
	public void constract(FileBuilder fb) {
		fb.fileHead();
		fb.fileBody();
		fb.fileTail();
		fb.getResult();
	}
}
import java.util.Date;

public abstract class FileBuilder {
	protected String no;//分公司编号
	protected Date date;// 导出日期
	protected String tablename;//表名
	protected String username;//输出人
	
	public abstract void fileHead();
	public abstract void fileBody();
	public abstract void fileTail();
	public abstract void getResult();
	
	
	public FileBuilder(String no, Date date, String tablename, String username) {
		this.no = no;
		this.date = date;
		this.tablename = tablename;
		this.username = username;
	}
	
}
import java.util.Date;

public class TextFileBuilder extends FileBuilder{

	public TextFileBuilder(String no, Date date, String tablename, String username) {
		super(no, date, tablename, username);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void fileHead() {
		System.out.println("导出数据为文本文件");
		System.out.println("文本文件头:");
		System.out.println("分公司编号:"+no);
		System.out.println("导出日期:"+date);
	}

	@Override
	public void fileBody() {
		System.out.println("文本文件体:");
		System.out.println("表名:"+tablename);	
	}

	@Override
	public void fileTail() {
		System.out.println("文本文件尾:");
		System.out.println("输出人:"+username);	
	}

	@Override
	public void getResult() {
		System.out.println("已导出完毕");	
	}

}
package com.data;

import java.util.Date;

public class XmlFileBuilder extends FileBuilder{

	public XmlFileBuilder(String no, Date date, String tablename, String username) {
		super(no, date, tablename, username);
		// TODO Auto-generated constructor stub
	}
	@Override
	public void fileHead() {
		System.out.println("导出数据为XML文件");
		System.out.println("文本文件头:");
		System.out.println("分公司编号:"+no);
		System.out.println("导出日期:"+date);
	}

	@Override
	public void fileBody() {
		System.out.println("文本文件体:");
		System.out.println("表名:"+tablename);	
	}

	@Override
	public void fileTail() {
		System.out.println("文本文件尾:");
		System.out.println("输出人:"+username);	
	}

	@Override
	public void getResult() {
		System.out.println("已导出完毕");	
	}
}
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Client {

	public static void main(String[] args) throws ParseException {
		Director director=new Director();
		SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
		Date date1 = dateformat.parse("2022-4-19");
		Date date2 = dateformat.parse("2022-4-20");
		
		FileBuilder fb1=new TextFileBuilder("001",date1,"student","李华");
		FileBuilder fb2=new XmlFileBuilder("002",date2,"company","李四");

		director.constract(fb1);
		director.constract(fb2);	
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值