建造者模式

问:建造者模式要解决什么问题。什么时候使用此模式?

比如我们组装一台电脑主机。必要的硬件有CPU 、硬盘、电源、内存、主板。非必要的有独立网卡、散热器。独立显卡等等。


构造函数创建对象

主机

package com.lyy.pattern.builder;

/**
 * 电脑主机
 * @author ThinkPad
 *
 */
public class ComputerMain {


	//cpu 	必要
	private String cpu;
	
	//内存	 必要
	private String memory;
	
	//电源	 必要
	private String power;
	
	//硬盘 	必要
	private String disk;
	
	//主板       必要
	private String mainboard;
	
	//独立网卡 		非必要
	private String independentNetworkCar; 
	
	//散热风扇 	 	非必要
	private String coolingFan;

	/**
	 * 最基本构造函数
	 * @param cpu
	 * @param memory
	 * @param power
	 * @param disk
	 */
	public ComputerMain(String cpu, String memory, String power, String disk, String mainboard) {
		this(cpu,memory,power,disk, mainboard, null, null);
	}
	
	/**
	 * 增加一个网卡的构造函数
	 * @param cpu
	 * @param memory
	 * @param power
	 * @param disk
	 * @param independentNetworkCar
	 */
	public ComputerMain(String cpu, String memory, String power, String disk, 
				String mainboard,String independentNetworkCar) {
		this(cpu,memory,power,disk,mainboard,independentNetworkCar, null);
	}
	
	/**
	 * 增加一个网卡和散热器的造函数
	 * @param cpu
	 * @param memory
	 * @param power
	 * @param disk
	 * @param independentNetworkCar
	 * @param coolingFan
	 */
	public ComputerMain(String cpu, String memory, String power, String disk, 
				String mainboard, String independentNetworkCar, String coolingFan) {
		this.cpu = cpu;
		this.memory = memory;
		this.power = power;
		this.disk = disk;
		this.mainboard = mainboard;
		this.independentNetworkCar = independentNetworkCar;
		this.coolingFan = coolingFan;
}
	
	
	

	@Override
	public String toString() {
		return "ComputerMain [cpu=" + cpu + ", memory=" + memory + ", power=" + power + ", disk=" + disk
				+ ", mainboard=" + mainboard + ", independentNetworkCar=" + independentNetworkCar + ", coolingFan="
				+ coolingFan + "]";
	}

		
	
}


main:

package com.lyy.pattern.builder;

public class Main {
	
	
	public static void main(String[] args) {
		//基本电脑主机
		ComputerMain baseComputerMain = new ComputerMain("酷睿 i7", "金斯顿 ", "长城", "西部数据" ,"华硕");
		System.out.println(baseComputerMain);
		
		//有独立网上的电脑
		ComputerMain networkCarComputerMain = new ComputerMain("酷睿 i7", "金斯顿 ", "长城", "西部数据", "华硕", "inter");
		System.out.println(networkCarComputerMain);
		
		//有独立网卡和散热风扇的电脑
		ComputerMain advaComputerMain = new ComputerMain("酷睿 i7", "金斯顿 ", "长城", "西部数据","华硕" ,"inter","酷冷至尊");
		System.out.println(advaComputerMain);
		
		//有散热风扇的电脑
		ComputerMain fanComputerMain = new ComputerMain("酷睿 i7", "金斯顿 ", "长城", "西部数据","华硕" ,null,"酷冷至尊");
		System.out.println(fanComputerMain);
	}
}



上面我们用构造函数来创建对象有几个问题:

1.如果我们非必要的硬件增加独立显卡、固态硬盘、等;那么创建对象很麻烦。


2.如上面:想创建一个带散热器且不带独立网卡的主机时,我们就要在构造函数独立网卡对应位置填null



javaBean方式创建对象
用这种方式可解决上面第2个问题。

		//1.先创建一个基本主机
		ComputerMain baseComputerMain = new ComputerMain("酷睿 i7", "金斯顿 ", "长城", "西部数据" ,"华硕");
		//2.加个风扇
		baseComputerMain.setCoolingFan("酷冷至尊");
其他非必要硬件如上也可达到目的。


也有一个问题:


1.阻止了对象被创建完成后的不可变。比如说我们创建完主机,并开机运行,这时肯定是不能再换硬件或增加硬件。(对象创建完不想让改变状态)。但我们可随时调用set方法的。



解决方法:
package com.lyy.pattern.builder;

/**
 * 电脑主机
 * @author ThinkPad
 *
 */
public class ComputerMain2 {


	//cpu 	必要
	private String cpu;
	
	//内存	 必要
	private String memory;
	
	//电源	 必要
	private String power;
	
	//硬盘 	必要
	private String disk;
	
	//主板       必要
	private String mainboard;
	
	//独立网卡 		非必要
	private String independentNetworkCar; 
	
	//散热风扇 	 	非必要
	private String coolingFan;
	
	
	/**
	 * 构造函数
	 * @param builder
	 */
	public ComputerMain2(Builder builder) {
		this.coolingFan = builder.cpu;
		this.cpu = builder.cpu;
		this.disk = builder.disk;
		this.independentNetworkCar = builder.independentNetworkCar;
		this.mainboard = builder.mainboard;
		this.memory = builder.mainboard;
		this.power = builder.power;
	}
	

	/**
	 * 建造器
	 * @author ThinkPad
	 *
	 */
	public static class Builder{
		
		//cpu 	必要
		private String cpu;
		
		//内存	 必要
		private String memory;
		
		//电源	 必要
		private String power;
		
		//硬盘 	必要
		private String disk;
		
		//主板       必要
		private String mainboard;
		
		//独立网卡 		非必要
		private String independentNetworkCar; 
		
		//散热风扇 	 	非必要
		private String coolingFan;
		
		public Builder(String cpu, String memory, String power, String disk, String mainboard) {
			this.cpu = cpu;
			this.memory = memory;
			this.power = power;
			this.disk = disk;
			this.mainboard = mainboard;
		}


		public Builder setIndependentNetworkCar(String independentNetworkCar) {
			this.independentNetworkCar = independentNetworkCar;
			return this;
		}


		public Builder setCoolingFan(String coolingFan) {
			this.coolingFan = coolingFan;
			return this;
		}
		
		/**
		 * 创建主机对象
		 * @return
		 */
		public ComputerMain2 build() {
			return new ComputerMain2(this);
		}
		
		
	}

	@Override
	public String toString() {
		return "ComputerMain [cpu=" + cpu + ", memory=" + memory + ", power=" + power + ", disk=" + disk
				+ ", mainboard=" + mainboard + ", independentNetworkCar=" + independentNetworkCar + ", coolingFan="
				+ coolingFan + "]";
	}

	
	
		
	
}


		ComputerMain2 computerMain2 = new ComputerMain2.Builder("酷睿 i7", "金斯顿 ", "长城", "西部数据" ,"华硕")
				.setCoolingFan("酷冷至尊").build();
		System.out.println(computerMain2);


现在有这个一个场景:富士康有两个生产线。dell c20 、lenovo P50。既然是生产线那么生产本系列的电脑任何配置都是一样的。所以就没必要每次都set不同的硬件。但是还是以上的需求,开机运行不能修改硬件(创建的对象不能被修改某些参数,不提供set方法)。


上代码 :
package com.lyy.pattern.builder;

/**
 * 富士康
 * @author ThinkPad
 *
 */
public class Fushikang {

	public Computer createComputer(Builder builder) {
		//builder.setCpu()   builder.setMemory()...各各部分的创建这里省略了
		return builder.createComputer();
	}
}



package com.lyy.pattern.builder;

/**
 * 建造器接口
 * @author ThinkPad
 *
 */
public interface Builder {

	public String getCpu();
	
	public String getMemory();
	
	public String getPower();
	
	public String getDisk();
	
	public String getMainboard();
	
	public String getIndependentNetworkCar();
	
	public String getCoolingFan();
	
	public Computer createComputer();

}

package com.lyy.pattern.builder;


public class Computer {

	//cpu 	必要
	private String cpu;
	
	//内存	 必要
	private String memory;
	
	//电源	 必要
	private String power;
	
	//硬盘 	必要
	private String disk;
	
	//主板       必要
	private String mainboard;
	
	//独立网卡 		非必要
	private String independentNetworkCar; 
	
	//散热风扇 	 	非必要
	private String coolingFan;
	
	/**
	 * 构造器
	 * @param builder
	 */
	public Computer(Builder builder) {
		this.coolingFan = builder.getCoolingFan();
		this.cpu = builder.getCpu();
		this.disk = builder.getDisk();
		this.independentNetworkCar = builder.getIndependentNetworkCar();
		this.mainboard = builder.getMainboard();
		this.memory = builder.getMemory();
		this.power = builder.getPower();
	}

	@Override
	public String toString() {
		return "Computer [cpu=" + cpu + ", memory=" + memory + ", power=" + power + ", disk=" + disk + ", mainboard="
				+ mainboard + ", independentNetworkCar=" + independentNetworkCar + ", coolingFan=" + coolingFan + "]";
	}
	
	
	
}
package com.lyy.pattern.builder;

/**
 *戴尔c20生产线
 * @author ThinkPad
 *
 */
public class ProductionLineDellBuilder implements Builder {

	public String getCpu() {
		// TODO Auto-generated method stub
		return "I5-5820";
	}

	public String getMemory() {
		// TODO Auto-generated method stub
		return "威刚";
	}

	public String getPower() {
		// TODO Auto-generated method stub
		return "戴尔";
	}

	public String getDisk() {
		// TODO Auto-generated method stub
		return "戴尔";
	}

	public String getMainboard() {
		// TODO Auto-generated method stub
		return "戴尔";
	}

	public String getIndependentNetworkCar() {
		// TODO Auto-generated method stub
		return "戴尔";
	}

	public String getCoolingFan() {
		// TODO Auto-generated method stub
		return "戴尔";
	}

	public Computer createComputer() {
		
		return new Computer(this);
	}

}

package com.lyy.pattern.builder;

/**
 * 联想 P50生产线
 * @author ThinkPad
 *
 */
public class ProductionLineLenovoBuilder implements Builder {

	public String getCpu() {
		// TODO Auto-generated method stub
		return "AMD X8500";
	}

	public String getMemory() {
		// TODO Auto-generated method stub
		return "威刚";
	}

	public String getPower() {
		// TODO Auto-generated method stub
		return "联想";
	}

	public String getDisk() {
		// TODO Auto-generated method stub
		return "联想";
	}

	public String getMainboard() {
		// TODO Auto-generated method stub
		return "联想";
	}

	public String getIndependentNetworkCar() {
		// TODO Auto-generated method stub
		return "联想";
	}

	public String getCoolingFan() {
		// TODO Auto-generated method stub
		return "联想";
	}

	public Computer createComputer() {
		
		return new Computer(this);
	}

}
main
		Fushikang fushikang = new Fushikang();
		Computer dellComputer = fushikang.createComputer(new ProductionLineDellBuilder());
		Computer lenovoComputer = fushikang.createComputer(new ProductionLineLenovoBuilder());
		System.out.println(dellComputer);
		System.out.println(lenovoComputer);

打印
Computer [cpu=I5-5820, memory=威刚, power=戴尔, disk=戴尔, mainboard=戴尔, independentNetworkCar=戴尔, coolingFan=戴尔]
Computer [cpu=AMD X8500, memory=威刚, power=联想, disk=联想, mainboard=联想, independentNetworkCar=联想, coolingFan=联想]

总结(个人结论,不一定对!~~):
创建一个多属性或复杂对象、并且创建完的实例某些参数不想被修改(不提供set方法)时可考虑建造者模式。



最后给张类图:


基于python实现的粒子群的VRP(车辆配送路径规划)问题建模求解+源码+项目文档+算法解析,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档 算法设计的关键在于如何向表现较好的个体学习,标准粒子群算法引入惯性因子w、自我认知因子c1、社会认知因子c2分别作为自身、当代最优解和历史最优解的权重,指导粒子速度和位置的更新,这在求解函数极值问题时比较容易实现,而在VRP问题上,速度位置的更新则难以直接采用加权的方式进行,一个常见的方法是采用基于遗传算法交叉算子的混合型粒子群算法进行求解,这里采用顺序交叉算子,对惯性因子w、自我认知因子c1、社会认知因子c2则以w/(w+c1+c2),c1/(w+c1+c2),c2/(w+c1+c2)的概率接受粒子本身、当前最优解、全局最优解交叉的父代之一(即按概率选择其中一个作为父代,不加权)。 算法设计的关键在于如何向表现较好的个体学习,标准粒子群算法引入惯性因子w、自我认知因子c1、社会认知因子c2分别作为自身、当代最优解和历史最优解的权重,指导粒子速度和位置的更新,这在求解函数极值问题时比较容易实现,而在VRP问题上,速度位置的更新则难以直接采用加权的方式进行,一个常见的方法是采用基于遗传算法交叉算子的混合型粒子群算法进行求解,这里采用顺序交叉算子,对惯性因子w、自我认知因子c1、社会认知因子c2则以w/(w+c1+c2),c1/(w+c1+c2),c2/(w+c1+c2)的概率接受粒子本身、当前最优解、全局最优解交叉的父代之一(即按概率选择其中一个作为父代,不加权)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值