如何以正确的方式实现构建器设计模式?

问题描述

在学习设计模式时,我发现了 Builder 模式的不同实现。一些实现使用接口/抽象类来表示构建器,其他实现只使用静态类。 哪一种是实现构建器设计模式的正确方法

下面是一个使用抽象类 (ComputerBuilder) (Source) 的实现

 public class LaptopBuilder : ComputerBuilder
    {

        Computer computer;

         public LaptopBuilder()

        {

            computer = new Computer("Laptop");

        }

        public override void BuildOS()

        {

            //Todo

        }

        public override void BuildDevice()

        {

            //Todo

        }

        public Computer ComputerType

        {

            get { return computer; }

        }

    }

    public class DesktopBuilder : ComputerBuilder

    {

        Computer computer;

        public DesktopBuilder()

        {

            computer = new Computer("Desktop");

        }

        public override void BuildOS()

        {

            //Todo

        }

         public override void BuildDevice()

        {

            //Todo

        }

         public Computer ComputerType

        {

            get { return computer; }

        }

    }

下面是另一个实现,既不使用抽象类也不使用接口,而是使用静态类。 (Source)

public class User 
{
    //All final attributes
    private final String firstName; // required
    private final String lastName; // required
    private final int age; // optional
    private final String phone; // optional
    private final String address; // optional
 
    private User(UserBuilder builder) {
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
        this.age = builder.age;
        this.phone = builder.phone;
        this.address = builder.address;
    }
 
    //All getter,and NO setter to provde immutability
    public String getFirstName() {
        return firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public int getAge() {
        return age;
    }
    public String getPhone() {
        return phone;
    }
    public String getAddress() {
        return address;
    }
 
    @Override
    public String toString() {
        return "User: "+this.firstName+","+this.lastName+","+this.age+","+this.phone+","+this.address;
    }
 
    public static class UserBuilder 
    {
        private final String firstName;
        private final String lastName;
        private int age;
        private String phone;
        private String address;
 
        public UserBuilder(String firstName,String lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
        }
        public UserBuilder age(int age) {
            this.age = age;
            return this;
        }
        public UserBuilder phone(String phone) {
            this.phone = phone;
            return this;
        }
        public UserBuilder address(String address) {
            this.address = address;
            return this;
        }
        //Return the finally consrcuted User object
        public User build() {
            User user =  new User(this);
            validateUserObject(user);
            return user;
        }
        private void validateUserObject(User user) {
            //Do some basic validations to check 
            //if user object does not break any assumption of system
        }
    }
}

解决方法

如果您真的阅读了second article,您可能会注意到它很早就指出

“我想说明的是,我将在本文中讨论的构建器模式与 GangOfFour“设计模式”一书中提到的略有不同。” (作者重点)

稍后,他或她写道:

“对我来说,构建器模式更像是 fluent interface。”

注意小限定符,对我来说

这应该告诉您,您看到的不是模式的“规范”表示,而是一种变体。

也就是说,这些表示是 variations of the same underlying idea

寻找表达概念的替代方式是可以的。我们应该小心,不要将四人帮的书提升到无懈可击的状态。

,

对我来说(双关语)Builder 是 GoF 模式的最佳示例,自该书出版以来已得到改进。我相信是来自 Effective Java 的 Josh Bloch 的版本普及了静态方法;但是有些源自博客文章的版本比 GoF 版本更有用和/或更简单。

当我回顾 GoF 的书时,我从来没有重读过 Builder 一章,因为有更好的选择。当然,您必须决定哪种选择更适合您