• 设计模式学习--------9.生成器模式学习


    场景:

         考虑导出数据的应用框架,通常在导出的数据形式上有一定的约定方式,对于不同的输出格式,处理步骤都是一样的,但

    每步的具体实现是不一样的,像导出成TXT和EXCEL的文本形式不一样,但是导出的数据都会分为文件头,文件体和文件

    尾.所以应该将处理步骤导出文件头,导出文件体,导出文件尾这几个固定步骤提炼出来,形成公共的处理过程.今后可能会

    有很多种不同输出格式的要求,这就需要在处理过程不变的情况下,能方便地切换不同的输出格式处理。


    定义:

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


    角色:

     Builder:

    生成器接口,定义创建一个Product对象所需的各个部件的操作。

    package com.kris.study;
    
    public interface Builder {
    	public void builderHead();
    	public void buidlerFoot();
        public void buildPart();
    }
    


    ConcreteBuilder:

    具体的生成器实现,实现各个部件的创建,并负责组装Product对象的各个部件,同时还提供一个让用户获取组装完成后

    的产品对象的方法.

    package com.kris.study;
    
    public class ConcreteBuilder implements Builder {
    
    	/**
    	 *   生成器最终构建的产品对象
    	 */
    	private Product resultProduct;
    	
    	public Product getResult(){
    		return resultProduct;
    	}
    	
    	@Override
    	public void buildPart() {
           //构建某个部件的功能处理
    		System.out.println("创建身体");
    	}
    
    	@Override
    	public void builderHead() {
    		System.out.println("创建头部");
    	}
    
    	@Override
    	public void buidlerFoot() {
    		System.out.println("创建腿部");
    	}
    
    }
    
    package com.kris.study;
    
    public class ConcreteBuilder2 implements Builder {
    
    	/**
    	 *   生成器最终构建的产品对象
    	 */
    	private Product resultProduct;
    	
    	public Product getResult(){
    		return resultProduct;
    	}
    	
    	@Override
    	public void builderHead() {
           System.out.println("创建触角");
    	}
    
    	@Override
    	public void buidlerFoot() {
    		 System.out.println("创建躯干");
    	}
    
    	@Override
    	public void buildPart() {
    		System.out.println("创建脚");
    	}
    
    }
    


    Director:

    指导者,主要用来使用Builder接口,以一个统一的过程来构建所需要的Product对象

    package com.kris.study;
    
    public class Director {
    	//持有当前需要使用的生成器对象
         private Builder builder;
         
         public Director(Builder builder){
        	 this.builder = builder;
         }
         
         /**
          * 指导生成器构建最终的产品对象
          */
        public void construct(){
        	 builder.builderHead();
        	 builder.buildPart();
             builder.buidlerFoot(); }}


    Product:

    产品,表示生成构建的复杂对象,包含多个部件。

    package com.kris.study;

    public interface Product {
        //定义产品的操作
    	public String foot();
    	public String head();
    	public String body();
    }
    
    
    

    Client:

    客户端

    package com.kris.study;
    
    public class Client {
        public static void main(String[] args) {
    		Builder builder = new ConcreteBuilder();
    		Director direc = new Director(builder);
    		direc.construct();
    		Builder builder2 = new ConcreteBuilder2();
    		Director direc2 = new Director(builder2);
    		direc2.construct();
    	}
    }
    


    原理分析:

    生成器模式的主要功能是构建复杂的产品,而且是细化的,分多个固定步骤构建的产品,这个构建的过程是统一的,不变的.

    将变化的部分放到生成器部分,只有配置不同的生成器,那么同样的构建过程,就能构建出不同的产品来。

    生成器两个很重要的部分:

    1.Builder接口,这里定义了如何构建各个部件,也就是知道每个部件的功能如何实现,以及如何装配这些产品

    2.Director指导者,Director负责整体的构建算法,知道如何组合来构建完整的产品.

    在Director实现整体构建算法时,遇到需要创建和组合具体部件时,就会委托给Builder完成。

    在实际应用中需要指导者Director和生成器Builder之间进行交互来构建产品,方式通过生成器方法的参数和返回值,来

    回地传递数据。


    采用Builder直接构建复杂的对象,通常会对Builder模式进行一定的简化.

    1.由于是用Builder模式来创建某个对象,因此没必要再定义一个Builder接口,提供一个具体构建器类就可以了。

    2.将指导者和Client功能合并起来,由Client去指导构建器去构造复杂对象

    3.将构建器和被构建对象合并,将类内联化。


    考虑一个实际应用,要创建一个合同对象,里面有很多属性值都有约束,要求创建出来的对象满足这些约束规则.约束规

    则比如,保险合同通常情况下可以和个人签订,也可以和某个公司签订,但是一份合同不能同时与个人和公司签订。

    package com.kris.study;
    
    public class InsuranceContract {
       private String contractId;
       
       private String personName;
       
       private String companyName;
       
       private long beginDate;
       
       private long endDate;
       
       private String otherData;
       
       private InsuranceContract(ConcreteBuilder builder){
    	   contractId = builder.contractId;
    	   personName = builder.personName;
    	   companyName = builder.companyName;
    	   beginDate = builder.beginDate;
    	   endDate = builder.endDate;
    	   otherData = builder.otherData;
       }
       
       public static class ConcreteBuilder{
    	   
    	   private String contractId;
    	   
    	   private String personName;
    	   
    	   private String companyName;
    	   
    	   private long beginDate;
    	   
    	   private long endDate;
    	   
    	   private String otherData;
    
    	public ConcreteBuilder(String contractId, long beginDate, long endDate) {
    		super();
    		this.contractId = contractId;
    		this.beginDate = beginDate;
    		this.endDate = endDate;
    	}
    
    
    	public ConcreteBuilder setPersonName(String personName) {
    		this.personName = personName;
    		return this;
    	}
    
    	public ConcreteBuilder setCompanyName(String companyName) {
    		this.companyName = companyName;
    		return this;
    	}
    
    	public ConcreteBuilder setOtherData(String otherData) {
    		this.otherData = otherData;
    		return this;
    	}
    
    	public InsuranceContract build(){
    		if(contractId == null || contractId.trim().length() == 0){
    			throw new IllegalArgumentException("合同编号不能为空");
    		}
    		
    		boolean signPerson = personName != null && personName.trim().length()>0;
    		boolean signCompany = companyName != null && companyName.trim().length()>0;
    		
    		if(signCompany && signPerson){
    			throw new IllegalArgumentException("一份合同不能同时与人和公司签订");
    		}
    		
    		if(signCompany == false && signPerson == false){
    			throw new IllegalArgumentException("一份合同不能没有签订对象");
    		}
    		
    		if(beginDate<=0){
    			throw new IllegalArgumentException("合同必须有保险开始生效的日期");
    		}
    		
    		if(endDate <=0){
    			throw new IllegalArgumentException("合同必须有保险失效生效的日期");
    		}
    		
    		if(endDate<=beginDate){
    			throw new IllegalArgumentException("保险失效的日期必须大于保险生效日期");
    		}
    		
    		return new InsuranceContract(this);
    	}
    	   
       }
       
       public void someOperation(){
    	   System.out.println("Now in Insurance Contract someOperation =="+this.contractId);
       }
    }
    
    package com.kris.study;
    
    public class Client {
    
    	
    	public static void main(String[] args) {
           InsuranceContract.ConcreteBuilder builder =
        		   new InsuranceContract.ConcreteBuilder("101", 102L, 67890L);
           InsuranceContract contract = builder.setPersonName("张三").
        		   setOtherData("test").build();
           contract.someOperation();
    	}
    
    }
    

    优点:
    松散耦合,更好的复用性,将构建算法和具体产品实现分离,这样使得构建产品的算法可以复用。
    本质: 分离整体构建算法和部件构造


  • 相关阅读:
    三个步骤,从零开始快速部署LoRaServer
    Java项目打包后 启动报java.nio.charset.MalformedInputException: Input length = 1异常
    iis中没有URL重写
    并发测试工具Jmeter
    IOS – OPenGL ES 调节图像饱和度 GPUImageSaturationFilter
    UImage – 色彩直方图 GPUImageHistogramGenerator
    IOS – OPenGL ES 调节图像伽马线 GPUImageGammaFilter
    GPUImage – 亮度平均 GPUImageLuminosity
    IOS – OpenGL ES 调节图像对比度 GPUImageContrastFilter
    IOS – OpenGL ES 调节图像RGB通道 GPUImageRGBFilter
  • 原文地址:https://www.cnblogs.com/krislight1105/p/3748385.html
Copyright © 2020-2023  润新知