大话设计模式-Java实现(13)-建造者模式

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

使用建造者模式的情景:
主要是用于创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化。

建造者模式的好处就是使得建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了。

举例:
当玩一个角色扮演类的游戏时,通常都需要创建一个角色,可以选择男性或女性,生成人物的打扮和武器也会根据选择的性别发生变化,但是男性和女性单独创建的流程都是固定不变的,即所有男性的打扮、武器都是固定的,这个生成角色的过程就可以用建造者模式实现。代码如下:

//Builder接口,用来定义构造对象需要的全部流程,并且有一个返回组装好的对象的方法
public interface IBuilder {
	
	public void buildSex();
	public void buildCloth();
	public void buildWeapon();
	public Person createPerson();
	
}
//角色类
public class Person {
	
	private String sex;
	private String cloth;
	private String weapon;
	
	public String getSex() {
		return sex;
	}
	
	public void setSex(String sex) {
		this.sex = sex;
	}
	
	public String getCloth() {
		return cloth;
	}
	
	public void setCloth(String cloth) {
		this.cloth = cloth;
	}
	
	public String getWeapon() {
		return weapon;
	}
	
	public void setWeapon(String weapon) {
		this.weapon = weapon;
	}
	
	public String show(){
		return "角色性别:" + sex + " 角色服饰:" + cloth + " 角色武器:" + weapon;
	}
	
}
//构建男性角色的类
public class BuildMan implements IBuilder {

	Person person;

	public BuildMan() {
		this.person = new Person();
	}

	@Override
	public void buildSex() {
		person.setSex("男");
		System.out.println("已选择男性角色进行创建");
	}

	@Override
	public void buildCloth() {
		person.setCloth("男性服饰");
		System.out.println("创建男性角色服装");
	}

	@Override
	public void buildWeapon() {
		person.setWeapon("男性武器");
		System.out.println("创建男性角色武器");
	}

	@Override
	public Person createPerson() {
		return this.person;
	}

}
//构建女性角色的类
public class BuildWomen implements IBuilder {

	Person person;

	public BuildWomen() {
		this.person = new Person();
	}

	@Override
	public void buildSex() {
		person.setSex("女");
		System.out.println("已选择女性角色进行创建");
	}

	@Override
	public void buildCloth() {
		person.setCloth("女性服装");
		System.out.println("创建女性角色服装");
	}

	@Override
	public void buildWeapon() {
		person.setWeapon("女性武器");
		System.out.println("创建女性角色武器");
	}

	@Override
	public Person createPerson() {
		return this.person;
	}

}
//主程序代码
public class Test1 {
	
    public static void main(String[] args) {
    	
        // 创建一个男性角色
        BuildMan man = new BuildMan();
        man.buildSex();
        man.buildCloth();
        man.buildWeapon();
        Person person1 = man.createPerson();
        System.out.println(person1.show());

        System.out.println("============");

        BuildWomen woman = new BuildWomen();
        woman.buildSex();
        woman.buildCloth();
        woman.buildWeapon();
        Person person2 = woman.createPerson();
        System.out.println(person2.show());
        
    }
    
}

运行结果如下:
在这里插入图片描述
仔细观察,所有生成角色的业务逻辑是一样的,必须要设置性别、服装和武器,少设置一个就会不符合业务逻辑。建造者模式就是把构造的流程放到一个专门指挥角色生成的对象中,由他负责去生成相应的属性,这样可以避免忘记生成某个属性,导致错误出现。下面添加这个指挥者类:

public class BuildDerector {
	
    public void BuildPerson(IBuilder builder) {
        builder.buildSex();
        builder.buildCloth();
        builder.buildWeapon();
    }
    
}

指挥者类只负责加工每个对象,不负责其他的业务逻辑。

//主程序代码
public class Test2 {
    public static void main(String[] args) {
    	
        // 创建一个男性角色
        BuildDerector buildDerector = new BuildDerector();
        
        BuildMan man = new BuildMan();
        buildDerector.BuildPerson(man);
        Person person1 = man.createPerson();
        System.out.println(person1.show());
        
        System.out.println("============");
        
        BuildWomen woman = new BuildWomen();
        buildDerector.BuildPerson(woman);
        Person person2 = woman.createPerson();
        System.out.println(person2.show());
        
    }
    
}

运行结果如下:
在这里插入图片描述
建造者模式和模板模式十分相似,都是按照一个模板去实现业务逻辑,以下部分是模板模式的代码实现:

//体育运动模板类
public abstract class Sports {

	public void start(){
		System.out.println("比赛开始,开始计时。");
	}

	public void end(){
		System.out.println("时间到,比赛结束。");
	}

	public abstract void process();

	// 使用final修饰,防止修改模板
	public final void play(){
		start();
		process();
		end();
	}
	
}
public class Basketball extends Sports {

	@Override
	public void process() {
		System.out.println("开始进行篮球比赛");
	}

}
public class Football extends Sports {

	@Override
	public void process() {
		System.out.println("开始进行足球比赛");
	}

}
//主程序代码
public class Test {

	public static void main(String[] args) {
		Sports sports = new Basketball();
        sports.play();
        System.out.println("=== another sport game ===");
        sports = new Football();
        sports.play();
	}

}

运行结果如下:
在这里插入图片描述
可以看出来,模板模式执行的业务逻辑都定义在了父类当中,所以每个子类都需要按照这个流程去执行。而建造者模式,虽然本次例子中,都是由同一个指挥者去执行,但指挥者类可以扩展出来子类,根据不同子类的建造者,采用不同的策略去执行,并且能保证同一个建造者实例化的对象执行的业务逻辑都相同,但是不同类的建造者实例化的对象执行的业务逻辑可以不相同。

模板模式的使用情景:
每个子类的业务逻辑基本一样;很多代码可以进行复用;进行系统维护升级的情况下,可以采用模板模式进行向下兼容,通过增加钩子判断相应的版本以及执行的流程。

建造者模式的使用场景:
很多子类都需要执行相同的方法,但是存在顺序、逻辑不完全相同的情况。

发布了79 篇原创文章 · 获赞 59 · 访问量 3623

猜你喜欢

转载自blog.csdn.net/qq_44458489/article/details/105025579