建造者模式
玩过data或者lol的应该都知道,每个英雄有很多属性组成,例如血量、魔法量、智力值、敏捷值、力量值,还有4个技能,在没有使用建造者模式时,我们创造一个英雄过程是这样的,调用无参构造创建英雄,然后给英雄设置各个属性,由于属性比较多,并且赋值时可能有先后顺序,所以创建过程非常复杂,万一其中我们忘了给英雄设置一个技能,那么就会产生bug,这当然是不行的,还有就是每次我们去创建一个英雄都要重复上面的工作,这也是相当麻烦的,那么怎么办呢?建造者模式就是为了解决这个问题。
建造者模式定义:将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。
建造者模式中有四种角色:
1、Builder:抽象建造者。它声明为创建一个Product对象的各个部件指定的抽象接口。
2、ConcreteBuilder:具体建造者。实现抽象接口,构建和装配各个部件。
3、Director:指挥者。构建一个使用Builder接口的对象。它主要是用于创建一个复杂的对象,它主要有两个作用,一是:隔离了客户与对象的生产过程,二是:负责控制产品对象的生产过程。
4、Product:产品角色。一个具体的产品对象。
建造者模式的适用场景是这样的:
1、当对象的构建过程十分复杂,需要与表示分离的时候。
2、当对象的表示有不同种类,需要加以区分的时候。
类图如下
示例代码
package builder; public class Hero { private String name; private long hitPoint; private long magicPoint; private long intelligence; private long power; private long agility; private String skill1; private String skill2; private String skill3; private String skill4; public long getHitPoint() { return hitPoint; } public void setHitPoint(long hitPoint) { this.hitPoint = hitPoint; } public long getMagicPoint() { return magicPoint; } public void setMagicPoint(long magicPoint) { this.magicPoint = magicPoint; } public long getIntelligence() { return intelligence; } public void setIntelligence(long intelligence) { this.intelligence = intelligence; } public long getPower() { return power; } public void setPower(long power) { this.power = power; } public long getAgility() { return agility; } public void setAgility(long agility) { this.agility = agility; } public String getSkill1() { return skill1; } public void setSkill1(String skill1) { this.skill1 = skill1; } public String getSkill2() { return skill2; } public void setSkill2(String skill2) { this.skill2 = skill2; } public String getSkill3() { return skill3; } public void setSkill3(String skill3) { this.skill3 = skill3; } public String getSkill4() { return skill4; } public void setSkill4(String skill4) { this.skill4 = skill4; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Hero() { super(); } public Hero(String name) { super(); this.name = name; } }
package builder; public interface HeroBuilder { void createHero(String name); Hero getHero(); void buildHitPoint(); void buildMagicPoint(); void buildIntelligence(); void buildPower(); void buildAgility(); void buildSkill1(); void buildSkill2(); void buildSkill3(); void buildSkill4(); }
package builder; public class ESBuilder implements HeroBuilder { private Hero hero; @Override public void createHero(String name) { hero = new Hero("ES"); } @Override public Hero getHero() { return hero; } @Override public void buildHitPoint() { hero.setHitPoint(500); } @Override public void buildMagicPoint() { hero.setMagicPoint(300); } @Override public void buildIntelligence() { hero.setIntelligence(20); } @Override public void buildPower() { hero.setPower(30); } @Override public void buildAgility() { hero.setAgility(10); } @Override public void buildSkill1() { hero.setSkill1("沟壑"); } @Override public void buildSkill2() { hero.setSkill2("强化图腾"); } @Override public void buildSkill3() { hero.setSkill3("余震"); } @Override public void buildSkill4() { hero.setSkill4("回音击"); } }
package builder; public class SFBuilder implements HeroBuilder { private Hero hero; @Override public void createHero(String name) { hero = new Hero("SF"); } @Override public Hero getHero() { return hero; } @Override public void buildHitPoint() { hero.setHitPoint(450); } @Override public void buildMagicPoint() { hero.setMagicPoint(300); } @Override public void buildIntelligence() { hero.setIntelligence(20); } @Override public void buildPower() { hero.setPower(20); } @Override public void buildAgility() { hero.setAgility(20); } @Override public void buildSkill1() { hero.setSkill1("毁灭阴影"); } @Override public void buildSkill2() { hero.setSkill2("支配死灵"); } @Override public void buildSkill3() { hero.setSkill3("魔王降临"); } @Override public void buildSkill4() { hero.setSkill4("魂之挽歌"); } }
package builder; public class Director { private HeroBuilder heroBuilder; public void setHeroBuilder(HeroBuilder heroBuilder) { this.heroBuilder = heroBuilder; } public Hero create() { heroBuilder.buildHitPoint(); heroBuilder.buildMagicPoint(); heroBuilder.buildIntelligence(); heroBuilder.buildPower(); heroBuilder.buildAgility(); heroBuilder.buildSkill1(); heroBuilder.buildSkill2(); heroBuilder.buildSkill3(); heroBuilder.buildSkill4(); return heroBuilder.getHero(); } }
通过建造者模式,我们将一个英雄的创建过程在Derictor中定义好,通过传入不同的HeroBuilder,即可完成对不同英雄的创建。
可以看到,建造者模式完成下如下的功能:将一个复杂对象的创建过程给封装起来,让客户只需要知道可以利用对象名或者类型就能够得到一个完整的对象实例,而不需要关心对象的具体创建过程;将对象的创建过程与对象本身隔离开了,使得细节依赖于抽象,符合依赖倒置原则。可以使用相同的创建过程来创建不同的产品对象。