将流畅的界面与构建器模式一起使用 [英] Using fluent interface with builder pattern

查看:99
本文介绍了将流畅的界面与构建器模式一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过在下面创建人员构建器对象来理解流利的构建器模式。我已经编写了想要使用的代码,但是在实现时遇到了问题。我的问题如下:

I'm trying to understand fluent builder pattern by creating the person builder object below. I've written the code as I would like to use it but am having issues with implementing it. My issues are as follows:


  1. 在调用 HavingJob()时,应创建然后可以仅使用适用于该工作的方法来配置该新工作,并最终将其添加到该人的 Jobs 集合中。感觉应该返回它,以便可以调用其他流畅的工作方法。不确定如何在允许该级别及更高级别的链接的同时实现该功能。

  2. 在实现 IJobBuilder 方法时,我没有访问他们在 HavingJob()方法中创建的特定作业,因为我需要返回 IJobBuilder 以限制流利与工作有关的方法。 HavingJob()的诀窍是什么,以便那些特定的作业方法可以在仍允许链接的同时执行特定的作业?

  3. 一旦走到以 IJobBuilder 结尾的流畅路径,我将无法再调用 Build() HavingJob()添加其他作业。对此的答案是否将是一个单独的 IJobBuilder 实现,该实现继承自 PersonBuilder

  1. When calling HavingJob(), this should create a new job that can then be configured using only applicable methods for a job and ultimately added to the Jobs collection of the person. It feels like should return it so that other fluent job methods can be called on it. Not sure how to implement that awhile allowing chaining at that level and above.
  2. When implementing the IJobBuilder methods, I don't have access to the specific job they created in the HavingJob() method because I need to return the IJobBuilder to restrict the fluent methods to only be the ones related to the job. What is the trick to HavingJob() so that those specific job methods can operate on a specific job while still allowing for chaining?
  3. Once I go down a fluent path that ends with IJobBuilder, I can no longer call Build() or HavingJob() to add additional jobs. Would the answer to that one be to have a separate implementation of IJobBuilder that inherits from PersonBuilder?



    public class Person
    {
        public string Name { get; set; }
        public List<Job> Jobs { get; set; }
        public List<Phone> Phones { get; set; }
    }

    public class Phone
    {
        public string Number { get; set; }
        public string Usage { get; set; }
    }

    public class Job
    {
        public string CompanyName { get; set; }
        public int Salary { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var p = PersonBuilder
                .Create()
                    .WithName("My Name")
                    .HavingPhone("222-222-2222")
                        .WithUsage("CELL")
                    .HavingJob()
                        .WithCompanyName("First Company")
                        .WithSalary(100)
                    .HavingJob()
                        .WithCompanyName("Second Company")
                        .WithSalary(200)
                .Build();

            Console.WriteLine(JsonConvert.SerializeObject(p));
        }
    }

    public class PersonBuilder : IJobBuilder
    {
        protected Person Person;
        public PersonBuilder() { Person = new Person(); }
        public static PersonBuilder Create() => new PersonBuilder();
        public PersonBuilder WithName(string name)
        {
            Person.Name = name;
            return this;
        }

        public PersonBuilder HavingPhone(string phoneNumber)
        {
            // Need instance of phone
            return this;
        }

        public PersonBuilder WithUsage(string phoneUsage)
        {
            // Need instance of phone
            return this;
        }

        public IJobBuilder HavingJob()
        {
            // Need to create a job here and return it so that IJobBuilder methods work on specific instance right?
            return this;
        }

        public Person Build() => Person;

        public IJobBuilder WithCompanyName(string companyName)
        {
            // How do I set the company name if I don't have the job instance here
            job.CompanyName = companyName;
            return this;
        }

        public IJobBuilder WithSalary(int amount)
        {
            // How do I set the salary if I don't have a specific job instance here
            job.Salary = amount;
            return this;
        }
    }

    public interface IJobBuilder
    {
        IJobBuilder WithCompanyName(string companyName);
        IJobBuilder WithSalary(int salary);
    }


推荐答案

单一责任原则(SRP)和关注点分离(SoC)



工作创建者应负责构建工作

Single Responsibility Principle (SRP) and Separation of Concerns (SoC)

A Job Builder should be responsible for building a Job

public interface IJobBuilder {
    IJobBuilder WithCompanyName(string companyName);
    IJobBuilder WithSalary(int salary);
}

public class JobBuilder : IJobBuilder {
    private readonly Job job;

    public JobBuilder() {
        job = new Job();
    }

    public IJobBuilder WithCompanyName(string companyName) {
        job.CompanyName = companyName;
        return this;
    }

    public IJobBuilder WithSalary(int amount) {
        job.Salary = amount;
        return this;
    }

    internal Job Build() => job;
}

Person Builder应该负责构建Person。

A Person Builder should be responsible for building the Person.

public class PersonBuilder {
    protected Person Person;

    private PersonBuilder() { Person = new Person(); }

    public static PersonBuilder Create() => new PersonBuilder();

    public PersonBuilder WithName(string name) {
        Person.Name = name;
        return this;
    }

    public PersonBuilder HavingJob(Action<IJobBuilder> configure) {
        var builder = new JobBuilder();
        configure(builder);
        Person.Jobs.Add(builder.Build());
        return this;
    }

    public Person Build() => Person;

}

在上述构建器中,它将工作的构建委托给

In the above builder it delegates the building of the job to its responsible builder.

这会导致以下重构

class Program {
    static void Main(string[] args) {
        var p = PersonBuilder
            .Create()
                .WithName("My Name")
                .HavingJob(builder => builder
                    .WithCompanyName("First Company")
                    .WithSalary(100)
                )
                .HavingJob(builder => builder
                    .WithCompanyName("Second Company")
                    .WithSalary(200)
                )
            .Build();

        Console.WriteLine(JsonConvert.SerializeObject(p));
    }
}

这篇关于将流畅的界面与构建器模式一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆