设计模式之建造者模式

昨天回顾学习了工厂模式。工厂模式是给用户提供一个创建对象的简单方法,使用户不用关心其创建过程的具体细节。今天的建造者模式也同样是这个理念,不同的是,工厂模式一般创建的是内部结构比较简单,初始化比较复杂的类,比如打造零件;而建造者模式是用来创建比较复杂的类,内部有很多成员的类,比如一辆汽车,他包括了很多种零件。

一、定义

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

定义依然晦涩难懂。还是用生活中的例子举例。

你高兴地来到4s店准备买下一辆法拉利,选好车型后工作人员带你来到一个小房间告诉你要选配。于是你选了V12发动机红色车身赛车方向盘真皮座椅最新的曲面液晶仪表盘。在这个过程中,你不需要知道这些配件是如何装到你的法拉利上的但你最终会得到一辆你要求的法拉利。这个过程就是建造者模式。具体选配的安装,由具体的建造者来负责

二、结构

一般的建造者模式由4个角色构成:

  1. 抽象建造者(Builder):它为产品对象的各个部件指定抽象接口。

  2. 具体建造者(ConcreteBuilder):它是抽象建造者的实现。

  3. 产品(Product):它是建造者最终要建造出来的类,

  4. 指挥者(Director):它负责指挥建造者。

三、代码实现

现在我们就来模拟一下买车的过程。

首先需要一个产品类Car

public class Car {
​
    // 发动机
    private String engine;
    // 方向盘
    private String steeringWheel;
    // 座椅
    private String chair;
    // 仪表盘
    private String dashboard;
    // 车身颜色
    private String color;
​
    // 省略get和set方法
​
    @Override
    public String toString() {
        return "Car{" +
                "engine='" + engine + '\'' +
                ", steeringWheel='" + steeringWheel + '\'' +
                ", chair='" + chair + '\'' +
                ", dashboard='" + dashboard + '\'' +
                ", color='" + color + '\'' +
                '}';
    }
}

然后来一个抽象建造者

public abstract class CarBuilder {
​
    Car mCar;
​
    public CarBuilder() {
        mCar = new Car();
    }
​
    public abstract void buildEngine(String engine);
​
    public abstract void buildSteeringWheel(String steeringWheel);
​
    public abstract void buildChair(String chair);
​
    public abstract void buildDashboard(String dashboard);
​
    public abstract void buildColor(String color);
​
    public Car build() {
        return mCar;
    }
​
}

为什么需要抽象建造者?因为有不同的汽车厂商,他们对不同部件的创建方法有所不同。比如现在有法拉利和保时捷可选。

public class FerrariBuilder extends CarBuilder{
​
    @Override
    public void buildEngine(String engine) {
        System.out.println("用法拉利的方式安装引擎");
        mCar.setEngine(engine);
    }
​
    @Override
    public void buildSteeringWheel(String steeringWheel) {
        System.out.println("用法拉利的方式安装方向盘");
        mCar.setSteeringWheel(steeringWheel);
    }
​
    @Override
    public void buildChair(String chair) {
        System.out.println("用法拉利的方式安装座椅");
        mCar.setChair(chair);
    }
​
    @Override
    public void buildDashboard(String dashboard) {
        System.out.println("用法拉利的方式安装仪表盘");
        mCar.setDashboard(dashboard);
    }
​
    @Override
    public void buildColor(String color) {
        System.out.println("用法拉利的方式喷漆");
        mCar.setColor(color);
    }
}
public class PorscheBuilder extends CarBuilder{
​
    @Override
    public void buildEngine(String engine) {
        System.out.println("用保时捷的方式安装引擎");
        mCar.setEngine(engine);
    }
​
    @Override
    public void buildSteeringWheel(String steeringWheel) {
        System.out.println("用保时捷的方式安装方向盘");
        mCar.setSteeringWheel(steeringWheel);
    }
​
    @Override
    public void buildChair(String chair) {
        System.out.println("用保时捷的方式安装座椅");
        mCar.setChair(chair);
    }
​
    @Override
    public void buildDashboard(String dashboard) {
        System.out.println("用保时捷的方式安装仪表盘");
        mCar.setDashboard(dashboard);
    }
​
    @Override
    public void buildColor(String color) {
        System.out.println("用保时捷的方式喷漆");
        mCar.setColor(color);
    }
}

然后我们还需要一个指挥者来指挥他们造车

public class Direct {
    
    private CarBuilder mBuilder;
​
    public Direct(CarBuilder builder) {
        this.mBuilder = builder;
    }
    
    public Car createCar(String engine, String steeringWheel, String chair, String dashboard, String color) {
        mBuilder.buildEngine(engine);
        mBuilder.buildSteeringWheel(steeringWheel);
        mBuilder.buildChair(chair);
        mBuilder.buildColor(color);
        mBuilder.buildDashboard(dashboard);
        return mBuilder.build();
    }
}

最终用户来买车,只需要告诉自己的需求,就能得到一辆装好的车。

public class Client {
​
    public static void main(String[] args) {
        Direct direct = new Direct(new FerrariBuilder());
        Car car = direct.createCar(
                "V12", "赛车方向盘", "真皮座椅", "曲屏液晶仪表盘", "红色");
        System.out.println(car.toString());
    }
    
}

最终的运行结果:

 

省略Director

Director的作用是告诉建造者应该怎么建造,以什么样的顺序建造。所以如果对于建造顺序有一定的要求,就需要有一个Director来负责。但是如果没有顺序要求,那我们可以省略掉Director这个角色,使代码更精简。

这时我们先修改一下产品类,一般产品都会有默认的属性.

public class Car {
​
    // 发动机
    private String engine = "默认发动机";
    // 方向盘
    private String steeringWheel = "默认方向盘";
    // 座椅
    private String chair = "默认座椅";
    // 仪表盘
    private String dashboard = "默认仪表盘";
    // 车身颜色
    private String color = "默认颜色";
​
    ...
}

然后修改CarBuilder

public abstract class CarBuilder {
​
    Car mCar = new Car();
​
    public abstract CarBuilder buildEngine(String engine);
​
    public abstract CarBuilder buildSteeringWheel(String steeringWheel);
​
    public abstract CarBuilder buildChair(String chair);
​
    public abstract CarBuilder buildDashboard(String dashboard);
​
    public abstract CarBuilder buildColor(String color);
    
    public Car build() {
        return mCar;
    }
}

注意这里我们将抽象方法的返回值改成了CarBuilder,这是省略Director的关键。

然后修改具体的建造者

public class PorscheBuilder extends CarBuilder {
​
    @Override
    public CarBuilder buildEngine(String engine) {
        System.out.println("用保时捷的方式安装引擎");
        mCar.setEngine(engine);
        return this;
    }
​
    @Override
    public CarBuilder buildSteeringWheel(String steeringWheel) {
        System.out.println("用保时捷的方式安装方向盘");
        mCar.setSteeringWheel(steeringWheel);
        return this;
    }
​
    @Override
    public CarBuilder buildChair(String chair) {
        System.out.println("用保时捷的方式安装座椅");
        mCar.setChair(chair);
        return this;
    }
​
    @Override
    public CarBuilder buildDashboard(String dashboard) {
        System.out.println("用保时捷的方式安装仪表盘");
        mCar.setDashboard(dashboard);
        return this;
    }
​
    @Override
    public CarBuilder buildColor(String color) {
        System.out.println("用保时捷的方式喷漆");
        mCar.setColor(color);
        return this;
    }
}

这里的每一次buildXXX,我们都返回了Buidler本身。

最终用户就可以这样使用

public class Client {
​
    public static void main(String[] args) {
        CarBuilder builder = new PorscheBuilder();
        Car car = builder.buildEngine("V12发动机")
                .buildSteeringWheel("赛车方向盘")
                .buildColor("红色")
                .buildChair("真皮座椅")
                .buildDashboard("曲面液晶仪表盘")
                .build();
        System.out.println(car.toString());
    }
}

这也就是链式编程。省略Director也是目前使用的比较多的。

运行效果如下:

 

四、特点

  • 建造者模式相比较于工厂模式,它能够创建一个复杂的对象,并且用户不需要知道其创建的细节。并且每一个具体的建造者都相对独立,要增加新的建造者无需修改原本的代码,符合开闭原则。

  • 建造者模式的缺点在于如果产品内部变化复杂,可能需要定义很多的建造者,会使系统变得庞大。

五、适用环境

  1. 当需要生产的对象有复杂的内部结构,而用户只用指定类型而无需知道创建细节的情况。

  2. 生产对象内部有一定顺序要求的情况,可以使用Director来限定创建顺序。

内容概要:本文探讨了在MATLAB/SimuLink环境中进行三相STATCOM(静态同步补偿器)无功补偿的技术方法及其仿真过程。首先介绍了STATCOM作为无功功率补偿装置的工作原理,即通过调节交流电压的幅值和相位来实现对无功功率的有效管理。接着详细描述了在MATLAB/SimuLink平台下构建三相STATCOM仿真模型的具体步骤,包括创建新模型、添加电源和负载、搭建主电路、加入控制模块以及完成整个电路的连接。然后阐述了如何通过对STATCOM输出电压和电流的精确调控达到无功补偿的目的,并展示了具体的仿真结果分析方法,如读取仿真数据、提取关键参数、绘制无功功率变化曲线等。最后指出,这种技术可以显著提升电力系统的稳定性与电能质量,展望了STATCOM在未来的发展潜力。 适合人群:电气工程专业学生、从事电力系统相关工作的技术人员、希望深入了解无功补偿技术的研究人员。 使用场景及目标:适用于想要掌握MATLAB/SimuLink软件操作技能的人群,特别是那些专注于电力电子领域的从业者;旨在帮助他们学会建立复杂的电力系统仿真模型,以便更好地理解STATCOM的工作机制,进而优化实际项目中的无功补偿方案。 其他说明:文中提供的实例代码可以帮助读者直观地了解如何从零开始构建一个完整的三相STATCOM仿真环境,并通过图形化的方式展示无功补偿的效果,便于进一步的学习与研究。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值