class Person : IPerson { private string Name { get; } private string Surname { get; } private IContact PrimaryContact { get; set; } private IList<IContact> AllContacts { get; } public Person(string name, string surname, IContact primaryContact) { if (string.IsNullOrEmpty(name)) throw new ArgumentException(nameof(name)); if (string.IsNullOrEmpty(surname)) throw new ArgumentException(nameof(surname)); this.Name = name; this.Surname = surname; this.AllContacts = new List<IContact>(); this.SetPrimaryContact(primaryContact); } public void SetPrimaryContact(IContact contact) { this.AddContact(contact); this.PrimaryContact = contact; } public void AddContact(IContact contact) { if (contact == null) throw new ArgumentNullException(nameof(contact)); this.AllContacts.Add(contact); } }
interface IContact { } class PhoneNumber : IContact { private string AreaCode { get; } private string Number { get; } public PhoneNumber(string areaCode, string number) { if (string.IsNullOrEmpty(areaCode)) throw new ArgumentException(nameof(areaCode)); if (string.IsNullOrEmpty(number)) throw new ArgumentException(nameof(number)); this.AreaCode = areaCode; this.Number = number; } } class EmailAddress : IContact { private string Address { get; } public EmailAddress(string address) { if (string.IsNullOrEmpty(address)) throw new ArgumentException(nameof(address)); this.Address = address; } }
طراحی PersonBuilder :
interface IPerson { void SetPrimaryContact(IContact primaryContact); void AddContact(IContact contact); } interface IPersonBuilder { void SetName(string name); void SetSurname(string surname); void SetPrimaryContact(IContact primaryContact); void AddContact(IContact contact); IPerson Build(); }
class PersonBuilder: IPersonBuilder { private string Name { get; set; } private string Surname { get; set; } private IContact PrimaryContact { get; set; } private IList<IContact> OtherContacts { get; } = new List<IContact>(); public void SetName(string name) { if (string.IsNullOrEmpty(name)) throw new ArgumentException(nameof(name)); this.Name = name; } public void SetSurname(string surname) { if (string.IsNullOrEmpty(surname)) throw new ArgumentException(nameof(surname)); this.Surname = surname; } public void SetPrimaryContact(IContact primaryContact) { if (primaryContact == null) throw new ArgumentNullException(nameof(primaryContact)); this.PrimaryContact = primaryContact; } public void AddContact(IContact contact) { if (contact == null) throw new ArgumentNullException(nameof(contact)); this.OtherContacts.Add(contact); } public IPerson Build() { IPerson person = new Person(this.Name, this.Surname, this.PrimaryContact); foreach (IContact contact in this.OtherContacts) person.AddContact(contact); return person; } }
راه حل: استفاده از Interface Segregation principle در PersonBuilder :
class PersonBuilder { private PersonBuilder() { } public static IExpectSurnamePersonBuilder WithName(string name) { ... } }
پس به ازای هر کدام از عملیاتها، یک اینترفیس خواهیم داشت:
interface IExpectSurnamePersonBuilder { IExpectPrimaryContactPersonBuilder WithSurname(string surname); } interface IExpectPrimaryContactPersonBuilder { IExpectOtherContactsPersonBuilder WithPrimaryContact(IContact contact); } interface IExpectOtherContactsPersonBuilder { IExpectOtherContactsPersonBuilder WithOtherContact(IContact contact); IPersonBuilder WithNoMoreContacts(); } interface IPersonBuilder { IPerson Build(); }
class PersonBuilder : IExpectSurnamePersonBuilder, IExpectPrimaryContactPersonBuilder, IExpectOtherContactsPersonBuilder, IPersonBuilder { private string Name { get; } private string Surname { get; set; } private IContact PrimaryContact { get; set; } private Person Person { get; set; } private PersonBuilder(string name) { if (string.IsNullOrEmpty(name)) throw new ArgumentException(nameof(name)); this.Name = name; } public static IExpectSurnamePersonBuilder WithName(string name) { return new PersonBuilder(name); } public IExpectPrimaryContactPersonBuilder WithSurname(string surname) { if (string.IsNullOrEmpty(surname)) throw new ArgumentException(nameof(surname)); this.Surname = surname; return this; } public IExpectOtherContactsPersonBuilder WithPrimaryContact(IContact contact) { if (contact == null) throw new ArgumentNullException(nameof(contact)); this.Person = new Person(this.Name, this.Surname, contact); return this; } public IExpectOtherContactsPersonBuilder WithOtherContact(IContact contact) { if (contact == null) throw new ArgumentNullException(nameof(contact)); this.Person.AddContact(contact); return this; } public IPersonBuilder WithNoMoreContacts() { return this; } public IPerson Build() { return this.Person; } }
IPerson person = PersonBuilder .WithName("Ali") .WithSurname("Karimi") .WithPrimaryContact(new EmailAddress("admin@gmail.com")) .WithOtherContact(new EmailAddress("Test1@work.com")) .WithOtherContact(new EmailAddress("Test2@home.com")) .WithNoMoreContacts() .Build();
چکیده: