不用建造者模式存在的问题:
需求:定义一个电脑类,并且实例化出电脑类的对象,以及给该对象的属性赋值。
这样做的缺点是:
1.客户端程序员,在实例化好产品的对象之后,必须为该对象的每一个属性赋值,这样对于客户端程序员来说太麻烦了。
2.这样做违反了迪米特法则。
这相当于你去赛格配电脑,商家把零件全给你,你自己取组装电脑。
建造者模式与工厂模式的区别:
工厂模式:都是直接实例化出一个类的对象即可。强调对象直接用。
建造者模式,是在实例化出类的对象之后,还要给对象的属性赋值。强调使用过程。
针对于问题,进行代码修改:
作者专门创建一个ComputerBuilder类,专门用于封装。
电脑建造者类,必须关联电脑产品。,直接实例化。
目前这种写法还不是建造者模式,目前的优点:
1.客户端程序员需要一个产品时,直接向建造者要即可,建造者封装了创建电脑的复杂过程。
目前的缺点:
1.封装的也太狠了!无论客户的需求什么,都是采用最高配置,这相当于你去配电脑,商家都会给你配最高配置的电脑。均是一种配置电脑的方式。
仅对于上述问题继续改进,针对于不同需求,我们需要创建不同的建造者,来分别生产不同配置的产品。
此外,还有高配和中配。需要注意的是,这仍然不是建造者模式:
优点:1.可以根据客户端的不同需求,使用不同的建造者来生产产品。
缺点:1.我们发现,多个不同的建造者中的代码,在重复!既然代码中出现了重复的代码,那就不合理。
2、建造的过程不稳定,如果在某个建造者创建产品的过程中,漏掉了某一步,或者多了某一步,也不会有报错。没有一个统一的标准。
针对于上述问题,修改代码。
创建一个建造者接口,把制作产品的具体步骤,稳定下来!
我们让建造者类,去实现建造者接口,接口中的方法步骤,类就必须都要实现,少实现一个抽象方法就会报错!
如何测试?注意:测试时需要先调用set方法设置属性。
这还不是建造者模式。
优点:建造者类中的建造过程是稳定的,不会漏掉某一步!这样当客户端想扩展建造者时,也不会漏掉某一步!
缺点:
1.代码仍然有重复。2.现在又变成了客户端配置电脑,违反了迪米特法则。这相当于,你去电脑城配电脑,虽然不用你亲自组装电脑,但是你必须“指挥”那个装机boy。
针对于上述问题,修改代码。
建造者模式,终于进化出来了。
把建造者传给指挥者,指挥者负责指挥,最终返回成品。(建造者)
这就是建造者模式:
优点:
1.创建对象的过程是稳定不变的(因为有ComputerBuilder接口稳定过程)
2.创建对象的过程只写了一次,没有重复代码(指挥者完成。)
3.需要扩展指挥者的时候,不用修改之前的代码,这符合了开闭原则。
工厂模式与建造者模式的区别:
工厂模式只需要一个简单的new, new出产品即可。
建造者模式更注重在new 出产品之后的,为产品属性赋值的过程。
建造者模式的UML类图
建造者模式的相关练习
package BuilderExercise.type1;
public class GameRole {
public static void main(String[] args) {
BoyGod boy = new BoyGod();
Director dr = new Director();
CoolBoy coolboy = new CoolBoy();
System.out.println(dr.build(boy));
System.out.println(dr.build(coolboy));
}
}
class Role{
//定义游戏角色需要的身体部位
private String face;
private String eyes;
private String body;
//提供相应的get和set方法
public String getFace() {
return face;
}
public void setFace(String face) {
this.face = face;
}
public String getEyes() {
return eyes;
}
public void setEyes(String eyes) {
this.eyes = eyes;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
//提供所需要的toString方法
@Override
public String toString() {
return "Role [face=" + face + ", eyes=" + eyes + ", body=" + body + "]";
}
}
interface MakeHuman{
void makeFace();
void makeEyes();
void makeBody();
Role getRole();
}
//创建一个男神角色
class BoyGod implements MakeHuman{
Role role = new Role();
@Override
public void makeFace() {
// TODO Auto-generated method stub
role.setFace("瓜子脸");
}
@Override
public void makeEyes() {
// TODO Auto-generated method stub
role.setEyes("大眼睛");
}
@Override
public void makeBody() {
// TODO Auto-generated method stub
role.setBody("器宇轩昂");
}
@Override
public Role getRole() {
return role;
}
}
//创建一个指挥者,指挥者负责流程的相关指挥工作。
class Director{
public Role build(MakeHuman human) {
human.makeFace();
human.makeEyes();
human.makeBody();
return human.getRole();
}
}
//创建一个型男角色
class CoolBoy implements MakeHuman{
Role role = new Role();
@Override
public void makeFace() {
// TODO Auto-generated method stub
role.setFace("国字脸");
}
@Override
public void makeEyes() {
// TODO Auto-generated method stub
role.setEyes("大眼睛");
}
@Override
public void makeBody() {
// TODO Auto-generated method stub
role.setBody("胸肌发达");
}
@Override
public Role getRole() {
return role;
}
}