CSharp: Builder Pattern in donet core 3
/// <summary>
/// Car is a ConcreteBuilder
/// 生成器 Builder Pattern
/// geovindu eidit
/// </summary>
class Car : IBuilder
{
/// <summary>
///
/// </summary>
private string brandName;
/// <summary>
///
/// </summary>
private Product product;
/// <summary>
///
/// </summary>
/// <param name="brand"></param>
public Car(string brand)
{
product = new Product();
this.brandName = brand;
}
/// <summary>
///
/// </summary>
public void StartUpOperations()
{ //Starting with brandname
product.Add("-----------");
product.Add($"Car model name :{this.brandName}");
}
/// <summary>
///
/// </summary>
public void BuildBody()
{
product.Add("This is a body of a Car");
}
/// <summary>
///
/// </summary>
public void InsertWheels()
{
product.Add("4 wheels are added");
}
/// <summary>
///
/// </summary>
public void AddHeadlights()
{
product.Add("2 Headlights are added");
}
/// <summary>
///
/// </summary>
public void EndOperations()
{
product.Add("-----------");
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public Product GetVehicle()
{
return product;
}
}
/// <summary>
/// "Director"
/// 生成器 Builder Pattern
/// geovindu eidit
/// </summary>
class Director
{
/// <summary>
///
/// </summary>
private IBuilder builder;
/*
* A series of steps.In real life, these steps
* can be much more complex.
*/
/// <summary>
///
/// </summary>
/// <param name="builder"></param>
public void Construct(IBuilder builder)
{
this.builder = builder;
builder.StartUpOperations();
builder.BuildBody();
builder.InsertWheels();
builder.AddHeadlights();
builder.EndOperations();
}
}
///<summary>
///The common interface
///生成器 Builder Pattern
///geovindu eidit
/// </summary>
interface IBuilder
{
/// <summary>
///
/// </summary>
void StartUpOperations();
/// <summary>
///
/// </summary>
void BuildBody();
/// <summary>
///
/// </summary>
void InsertWheels();
/// <summary>
///
/// </summary>
void AddHeadlights();
/// <summary>
///
/// </summary>
void EndOperations();
/// <summary>
///
/// </summary>
/// <returns></returns>
Product GetVehicle();
//An interface cannot contain instance field
//Product product;//error
}
/// <summary>
/// Motorcycle is another ConcreteBuilder
/// 生成器 Builder Pattern
/// geovindu eidit
/// </summary>
class Motorcycle : IBuilder
{
/// <summary>
///
/// </summary>
private string brandName;
/// <summary>
///
/// </summary>
private Product product;
/// <summary>
///
/// </summary>
/// <param name="brand"></param>
public Motorcycle(string brand)
{
product = new Product();
this.brandName = brand;
}
/// <summary>
///
/// </summary>
public void StartUpOperations()
{
product.Add("_________________");
}
/// <summary>
///
/// </summary>
public void BuildBody()
{
product.Add("This is a body of a Motorcycle");
}
/// <summary>
///
/// </summary>
public void InsertWheels()
{
product.Add("2 wheels are added");
}
/// <summary>
///
/// </summary>
public void AddHeadlights()
{
product.Add("1 Headlights are added");
}
/// <summary>
///
/// </summary>
public void EndOperations()
{
//Finishing up with brandname
product.Add($"Motorcycle model name :{this.brandName}");
product.Add("_________________");
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public Product GetVehicle()
{
return product;
}
}
/// <summary>
/// "Product"
/// 生成器 Builder Pattern
/// geovindu eidit
/// </summary>
class Product
{
// You can use any data structure that you prefer e.g.List<string> etc.
/// <summary>
///
/// </summary>
private LinkedList<string> parts;
/// <summary>
///
/// </summary>
public Product()
{
parts = new LinkedList<string>();
}
/// <summary>
///
/// </summary>
/// <param name="part"></param>
public void Add(string part)
{
//Adding parts
parts.AddLast(part);
}
/// <summary>
///
/// </summary>
public void Show()
{
Console.WriteLine("\nProduct completed as below :");
foreach (string part in parts)
Console.WriteLine(part);
}
}
/// <summary>
/// 生成器 Builder Pattern
/// geovindu eidit
/// </summary>
public class Person
{
public string Name, Position;
public override string ToString()
{
return $"{nameof(Name)}: {Name}, {nameof(Position)}: {Position}";
}
}
/// <summary>
/// 生成器 Builder Pattern
/// </summary>
/// <typeparam name="TSubject"></typeparam>
/// <typeparam name="TSelf"></typeparam>
public abstract class FunctionalBuilder<TSubject, TSelf>
where TSelf : FunctionalBuilder<TSubject, TSelf>
where TSubject : new()
{
/// <summary>
///
/// </summary>
private readonly List<Func<TSubject, TSubject>> actions
= new List<Func<TSubject, TSubject>>();
/// <summary>
///
/// </summary>
/// <param name="action"></param>
/// <returns></returns>
public TSelf Do(Action<TSubject> action)
=> AddAction(action);
/// <summary>
///
/// </summary>
/// <param name="action"></param>
/// <returns></returns>
private TSelf AddAction(Action<TSubject> action)
{
actions.Add(p => { action(p); return p; });
return (TSelf)this;
}
public TSubject Build()
=> actions.Aggregate(new TSubject(), (p, f) => f(p));
}
/// <summary>
/// 生成器 Builder Pattern
/// </summary>
public sealed class PersonBuilder
: FunctionalBuilder<Person, PersonBuilder>
{
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public PersonBuilder Called(string name)
=> Do(p => p.Name = name);
}
/// <summary>
/// 生成器 Builder Pattern
/// </summary>
public static class PersonBuilderExtensions
{
/// <summary>
///
/// </summary>
/// <param name="builder"></param>
/// <param name="position"></param>
/// <returns></returns>
public static PersonBuilder WorksAsA
(this PersonBuilder builder, string position)
{
builder.Do(p => p.Position = position) ;
return builder;
}
}
/// <summary>
/// 生成器 Builder Pattern
/// geovindu eidit
/// </summary>
public class MailService
{
/// <summary>
///
/// </summary>
public class EmailBuilder
{
/// <summary>
///
/// </summary>
public class Email
{
public string From, To, Subject, Body;
public override string ToString()
{
return $"{nameof(From)}: {From}, {nameof(To)}: {To}, {nameof(Subject)}: {Subject}, {nameof(Body)}: {Body}";
}
}
//
private readonly Email email;
/// <summary>
///
/// </summary>
/// <param name="email"></param>
public EmailBuilder(Email email) => this.email = email;
/// <summary>
///
/// </summary>
/// <param name="from"></param>
/// <returns></returns>
public EmailBuilder From(string from)
{
email.From = from;
return this;
}
/// <summary>
///
/// </summary>
/// <param name="to"></param>
/// <returns></returns>
public EmailBuilder To(string to)
{
email.To = to;
return this;
}
/// <summary>
///
/// </summary>
/// <param name="subject"></param>
/// <returns></returns>
public EmailBuilder Subject(string subject)
{
email.Subject = subject;
return this;
}
/// <summary>
///
/// </summary>
/// <param name="body"></param>
/// <returns></returns>
public EmailBuilder Body(string body)
{
email.Body = body;
return this;
}
}
/// <summary>
///
/// </summary>
/// <param name="email"></param>
private void SendEmailInternal(EmailBuilder.Email email) {
Console.WriteLine(email.ToString());
}
/// <summary>
///
/// </summary>
/// <param name="builder"></param>
public void SendEmail(Action<EmailBuilder> builder)
{
var email = new EmailBuilder.Email();
builder(new EmailBuilder(email));
SendEmailInternal(email);
}
}
/// <summary>
/// 生成器 Builder Pattern
/// geovindu eidit
/// </summary>
public class Person
{
public string Name;
public string Position;
public DateTime DateOfBirth;
public class Builder : PersonBirthDateBuilder<Builder>
{
internal Builder() { }
}
public static Builder New => new Builder();
public override string ToString()
{
return $"{nameof(Name)}: {Name}, {nameof(Position)}: {Position}";
}
}
/// <summary>
///
/// </summary>
public abstract class PersonBuilder
{
protected Person person = new Person();
public Person Build()
{
return person;
}
}
/// <summary>
///
/// </summary>
/// <typeparam name="SELF"></typeparam>
public class PersonInfoBuilder<SELF> : PersonBuilder
where SELF : PersonInfoBuilder<SELF>
{
public SELF Called(string name)
{
person.Name = name;
return (SELF)this;
}
}
/// <summary>
///
/// </summary>
/// <typeparam name="SELF"></typeparam>
public class PersonJobBuilder<SELF>
: PersonInfoBuilder</*PersonJobBuilder<SELF>*/SELF>
where SELF : PersonJobBuilder<SELF>
{
public SELF WorksAsA(string position)
{
person.Position = position;
return (SELF)this;
}
}
// here's another inheritance level
// note there's no PersonInfoBuilder<PersonJobBuilder<PersonBirthDateBuilder<SELF>>>!
/// <summary>
///
/// </summary>
/// <typeparam name="SELF"></typeparam>
public class PersonBirthDateBuilder<SELF>
: PersonJobBuilder<SELF>
where SELF : PersonBirthDateBuilder<SELF>
{
public SELF Born(DateTime dateOfBirth)
{
person.DateOfBirth = dateOfBirth;
return (SELF)this;
}
}
/// <summary>
/// 生成器 Builder Pattern
/// geovindu eidit
/// </summary>
public class Person
{
public Person()
{
Console.WriteLine("Creating an instance of Person");
}
// address
public string StreetAddress, Postcode, City;
// employment info
public string CompanyName, Position;
public int AnnualIncome;
public override string ToString()
{
return $"{nameof(StreetAddress)}: {StreetAddress}, {nameof(Postcode)}: {Postcode}," +
$" {nameof(City)}: {City}, {nameof(CompanyName)}: {CompanyName}," +
$" {nameof(Position)}: {Position}, {nameof(AnnualIncome)}: {AnnualIncome}";
}
}
/// <summary>
///
/// </summary>
public class PersonBuilder // facade
{
// the object we're going to build
protected Person person;
public PersonBuilder() => person = new Person();
protected PersonBuilder(Person person) => this.person = person;
public PersonAddressBuilder Lives => new PersonAddressBuilder(person);
public PersonJobBuilder Works => new PersonJobBuilder(person);
public static implicit operator Person(PersonBuilder pb)
{
return pb.person;
}
}
/// <summary>
///
/// </summary>
public class PersonJobBuilder : PersonBuilder
{
public PersonJobBuilder(Person person) : base(person) { }
public PersonJobBuilder At(string companyName)
{
person.CompanyName = companyName;
return this;
}
public PersonJobBuilder AsA(string position)
{
person.Position = position;
return this;
}
public PersonJobBuilder Earning(int annualIncome)
{
person.AnnualIncome = annualIncome;
return this;
}
}
/// <summary>
///
/// </summary>
public class PersonAddressBuilder : PersonBuilder
{
public PersonAddressBuilder(Person person) : base(person) { }
public PersonAddressBuilder At(string streetAddress)
{
person.StreetAddress = streetAddress;
return this;
}
public PersonAddressBuilder WithPostcode(string postcode)
{
person.Postcode = postcode;
return this;
}
public PersonAddressBuilder In(string city)
{
person.City = city;
return this;
}
}
调用:、
//生成器 Builder Pattern
Console.WriteLine("***Builder Pattern Demo.***");
//
Director director = new Director();
//
IBuilder b1 = new Car("福特");
//
IBuilder b2 = new Motorcycle("比亚迪");
// Making Car
director.Construct(b1);
//
Product p1 = b1.GetVehicle();
p1.Add("geovindu");
p1.Add("天下为公");
//
p1.Show();
//Making Motorcycle
//
director.Construct(b2);
//
Product p2 = b2.GetVehicle();
p2.Add("Geovin Du");
//
p2.Show();
// Console.ReadLine();
var b = new PersonBuilder();
var p = b.Called("Geovin 。。。Du")
.WorksAsA("软件开发者")
.Build();
Console.WriteLine(p.ToString());
//
var ms = new MailService();
ms.SendEmail(email => email.From("geovindu@dusystem.com")
.To("geovin@dusystem.com")
.Body("Hello, how are you? Geovin Du."));
var me = BuilderPattern.Inheritance.Person.New
.Called("六福齐天")
.WorksAsA("布心路")
.Born(DateTime.UtcNow)
.Build();
Console.WriteLine(me);
//
var pb = new BuilderPatternFacets.PersonBuilder();
BuilderPatternFacets.Person person = pb
.Lives
.At("10086 Buxin Road")
.In("Shenzhen")
.WithPostcode("518019")
.Works
.At("水贝珠宝")
.AsA("工程师")
.Earning(8123000);
Console.WriteLine(person);
输出:
***Builder Pattern Demo.*** Product completed as below : ----------- Car model name :福特 This is a body of a Car 4 wheels are added 2 Headlights are added ----------- geovindu 天下为公 Product completed as below : _________________ This is a body of a Motorcycle 2 wheels are added 1 Headlights are added Motorcycle model name :比亚迪 _________________ Geovin Du Name: Geovin 。。。Du, Position: 软件开发者 From: geovindu@dusystem.com, To: geovin@dusystem.com, Subject: , Body: Hello, how are you? Geovin Du. Name: 六福齐天, Position: 布心路 Creating an instance of Person StreetAddress: 10086 Buxin Road, Postcode: 518019, City: Shenzhen, CompanyName: 水贝珠宝, Position: 工程师, AnnualIncome: 8123000
哲学管理(学)人生, 文学艺术生活, 自动(计算机学)物理(学)工作, 生物(学)化学逆境, 历史(学)测绘(学)时间, 经济(学)数学金钱(理财), 心理(学)医学情绪, 诗词美容情感, 美学建筑(学)家园, 解构建构(分析)整合学习, 智商情商(IQ、EQ)运筹(学)生存.---Geovin Du(涂聚文)
浙公网安备 33010602011771号