本文介绍了将流畅的界面与构建器模式一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在尝试通过在下面创建人员构建器对象来理解流利的构建器模式。我已经编写了想要使用的代码,但是在实现时遇到了问题。我的问题如下:
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:
- 在调用
HavingJob()
时,应创建然后可以仅使用适用于该工作的方法来配置该新工作,并最终将其添加到该人的Jobs
集合中。感觉应该返回它,以便可以调用其他流畅的工作方法。不确定如何在允许该级别及更高级别的链接的同时实现该功能。 - 在实现
IJobBuilder
方法时,我没有访问他们在HavingJob()
方法中创建的特定作业,因为我需要返回IJobBuilder
以限制流利与工作有关的方法。HavingJob()
的诀窍是什么,以便那些特定的作业方法可以在仍允许链接的同时执行特定的作业? - 一旦走到以
IJobBuilder
结尾的流畅路径,我将无法再调用Build()
或HavingJob()
添加其他作业。对此的答案是否将是一个单独的IJobBuilder
实现,该实现继承自PersonBuilder
?
- 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 theJobs
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. - When implementing the
IJobBuilder
methods, I don't have access to the specific job they created in theHavingJob()
method because I need to return theIJobBuilder
to restrict the fluent methods to only be the ones related to the job. What is the trick toHavingJob()
so that those specific job methods can operate on a specific job while still allowing for chaining? - Once I go down a fluent path that ends with
IJobBuilder
, I can no longer callBuild()
orHavingJob()
to add additional jobs. Would the answer to that one be to have a separate implementation ofIJobBuilder
that inherits fromPersonBuilder
?
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));
}
}
这篇关于将流畅的界面与构建器模式一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!