建造者(Builder)
[TOC]
建造者在日常开发属于非常常见的一种设计模式了,核心也是将复杂对象的创建与使用进行剥离,Android开发中比较常见的就是Dialog的创建了,从Dialog中就能体会到这种设计模式的好处~
定义
建造者模式(Builder Pattern) 也叫做生成器模式
Separate the construction of a complex object from its representation so that the same construction process can create different representations.(将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。)
上面的专业术语定义写的很简单明了,说白了就是将一个五脏俱全的对象的构建和在应用中的使用做了一个剥离,而这样做的好处就是在类似场景下的使用可以使用相同的构建方法产生不一样的五脏俱全对象来
简单场景
还是使用英雄联盟的大背景来作为设计模式的应用场景,这里就先以简单的英雄为例,从构建英雄的基础属性开始
首先一个英雄需要具备固定的生命值,初始攻击,初始魔抗和初始物抗等等
coding
建造者模式首先需要具备4个角色
-
Product
需要构建的“五脏俱全”的对象,这里的“五脏俱全”指代对象具备相对复杂的功能
-
Builder抽象建造者
规范对象的创建抽象接口,所有对象都由此基类的子类产生
-
ConcreteBuilder具体建造者
实现抽象建造者方法的具体子类
-
Director导演类
负责实例化建造者的类,这里的写法也因人而异,开发者可以选择实现,书里有提到导演类一个很重要的作用,就是封装
导演类起到封装的作用, 避免高层模块深入到建造者内部的实现类
这里就先写一个简单的写法来实现建造者,对于builder的封装与否取决于具体业务的复杂程度,个人认为如果没有太过于复杂的业务依赖关系,仅仅是基础功能的封装,可以先不管导演类的装配,导演类主要起到的还是隔离业务和基础模块之间的直接调用关系
基础英雄和base工厂代码:
public class BaseHero {
protected String name;
protected String lifeValue;
protected String physicalAttack;
protected String magicAttack;
protected String physicalDefense;
protected String magicDefense;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLifeValue() {
return lifeValue;
}
public void setLifeValue(String lifeValue) {
this.lifeValue = lifeValue;
}
public String getPhysicalAttack() {
return physicalAttack;
}
public void setPhysicalAttack(String physicalAttack) {
this.physicalAttack = physicalAttack;
}
public String getMagicAttack() {
return magicAttack;
}
public void setMagicAttack(String magicAttack) {
this.magicAttack = magicAttack;
}
public String getPhysicalDefense() {
return physicalDefense;
}
public void setPhysicalDefense(String physicalDefense) {
this.physicalDefense = physicalDefense;
}
public String getMagicDefense() {
return magicDefense;
}
public void setMagicDefense(String magicDefense) {
this.magicDefense = magicDefense;
}
public BaseHero() {
}
@Override
public String toString() {
return "BaseHero{" +
"name='" + name + '\'' +
", lifeValue='" + lifeValue + '\'' +
", physicalAttack='" + physicalAttack + '\'' +
", magicAttack='" + magicAttack + '\'' +
", physicalDefense='" + physicalDefense + '\'' +
", magicDefense='" + magicDefense + '\'' +
'}';
}
public static abstract class BaseBuilder {
protected BaseHero mHero = onCreateHero();
protected abstract BaseHero onCreateHero();
public BaseHero build() {
return mHero;
}
}
}
具体英雄建造者实现:
public class HeroBuilder extends BaseHero.BaseBuilder {
@Override
protected BaseHero onCreateHero() {
BaseHero hero = new BaseHero();
hero.setLifeValue("1000生命值");
hero.setPhysicalAttack("20 攻击");
hero.setMagicAttack("10 法强");
hero.setMagicDefense("5 魔抗");
hero.setPhysicalDefense("10 物抗");
return hero;
}
public HeroBuilder setName(String name) {
mHero.setName(name);
return this;
}
public HeroBuilder setLifeValue(String lifeValue) {
mHero.setLifeValue(lifeValue);
return this;
}
public HeroBuilder setPhysicalAttack(String physicalAttack) {
mHero.setPhysicalAttack(physicalAttack);
return this;
}
public HeroBuilder setMagicAttack(String magicAttack) {
mHero.setMagicAttack(magicAttack);
return this;
}
public HeroBuilder setPhysicalDefense(String physicalDefense) {
mHero.setPhysicalDefense(physicalDefense);
return this;
}
public HeroBuilder setMagicDefense(String magicDefense) {
mHero.setMagicDefense(magicDefense);
return this;
}
}
最后是咱们的测试方法:
public static void main(String[] args) {
BaseHero hero1 = new HeroBuilder().setName("薇恩").setPhysicalAttack("30 攻击").build();
BaseHero hero2 = new HeroBuilder().setName("瑞兹").setMagicAttack("30 法强").build();
System.out.println(hero1.toString() + "\n" + hero2.toString());
}
//LOG
//BaseHero{name='薇恩', lifeValue='1000生命值', physicalAttack='30 攻击', magicAttack='10 法强', physicalDefense='10 物抗', magicDefense='5 魔抗'}
//BaseHero{name='瑞兹', lifeValue='1000生命值', physicalAttack='20 攻击', magicAttack='30 法强', physicalDefense='10 物抗', magicDefense='5 魔抗'}