使用带有构建器模式的流畅界面
Using fluent interface with builder pattern
我试图通过创建下面的 person builder 对象来理解流畅的构建器模式。我已经按照我想使用的方式编写了代码,但是在实现它时遇到了问题。我的问题如下:
- 当调用
HavingJob()
时,这应该创建一个新的工作,然后可以仅使用适用于工作的方法进行配置,并最终添加到该人的 Jobs
集合中。感觉应该 return 它以便可以在其上调用其他流畅的作业方法。不确定如何在允许在该级别及更高级别进行链接的同时实现它。
- 在实施
IJobBuilder
方法时,我无法访问他们在 HavingJob()
方法中创建的特定作业,因为我需要 return IJobBuilder
将流利的方法限制为仅与工作相关的方法。 HavingJob()
的诀窍是什么,以便那些特定的作业方法可以在特定的作业上运行,同时仍然允许链接?
- 一旦我走上以
IJobBuilder
结尾的流畅路径,我就不能再调用 Build()
或 HavingJob()
来添加其他作业。那个问题的答案是单独实现继承自 PersonBuilder
的 IJobBuilder
吗?
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)
Job Builder 应负责构建 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。
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;
}
在上面的构建器中,它将作业的构建委托给其负责的构建器。
这导致以下重构
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));
}
}
我试图通过创建下面的 person builder 对象来理解流畅的构建器模式。我已经按照我想使用的方式编写了代码,但是在实现它时遇到了问题。我的问题如下:
- 当调用
HavingJob()
时,这应该创建一个新的工作,然后可以仅使用适用于工作的方法进行配置,并最终添加到该人的Jobs
集合中。感觉应该 return 它以便可以在其上调用其他流畅的作业方法。不确定如何在允许在该级别及更高级别进行链接的同时实现它。 - 在实施
IJobBuilder
方法时,我无法访问他们在HavingJob()
方法中创建的特定作业,因为我需要 returnIJobBuilder
将流利的方法限制为仅与工作相关的方法。HavingJob()
的诀窍是什么,以便那些特定的作业方法可以在特定的作业上运行,同时仍然允许链接? - 一旦我走上以
IJobBuilder
结尾的流畅路径,我就不能再调用Build()
或HavingJob()
来添加其他作业。那个问题的答案是单独实现继承自PersonBuilder
的IJobBuilder
吗?
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)
Job Builder 应负责构建 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。
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;
}
在上面的构建器中,它将作业的构建委托给其负责的构建器。
这导致以下重构
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));
}
}