paint-brush
11 негізгі дизайн үлгілері: маңызды нұсқаулықбойынша@ssukhpinder
1,415 оқулар
1,415 оқулар

11 негізгі дизайн үлгілері: маңызды нұсқаулық

бойынша Sukhpinder Singh33m2024/09/08
Read on Terminal Reader

Тым ұзақ; Оқу

*Бағдарламалық құрал архитектурасын меңгеру: 11 негізгі дизайн үлгісі түсіндірілді* көмегімен бағдарламалық жасақтама архитектурасының құпияларын ашыңыз. Кітап C# бағдарламалау тілінде C# 8.0 жазылған. Зауыттарды құру үшін зауыт құру үшін пайдалануға болатын 11 дизайн үлгісі бар. Абстрактілі зауыт үлгісі кеңейту зауыттық әдісі болып табылады; зауыттық әдіспен өту ұсынылады.
featured image - 11 негізгі дизайн үлгілері: маңызды нұсқаулық
Sukhpinder Singh HackerNoon profile picture
0-item
1-item
2-item
3-item
4-item

Бағдарламалық жасақтама архитектурасын меңгеру арқылы бағдарламалық жасақтама архитектурасының құпияларын ашыңыз: 11 негізгі дизайн үлгілері түсіндірілді .

Мазмұны

  1. Дизайн үлгісі — абстрактілі фабрика
  • Оқу мақсаттары
  • Бастау
  • Дерексіз зауыт провайдерін қалай пайдалануға болады?
  • Шығару

2. Дизайн үлгісі — Адаптер

  • Use Case
  • Оқу мақсаттары
  • Бастау

3. Дизайн үлгісі — Құрылысшы

  • Use Case
  • Оқу мақсаттары
  • Бастау
  • Main() әдісінен құрастырушы үлгісін қалай пайдалануға болады
  • Шығару

4. Жауапкершілік үлгісін пайдалану жолы

  • Use Case
  • Бастау
  • Жауапкершілік тізбегі үлгісін қалай пайдалануға болады?
  • Шығару

5. Дизайн үлгісі — Декоратор

  • Use Case
  • Оқу мақсаттары
  • Бастау
  • Декоратор үлгісі әрекетте
  • Толық код
  • Шығару

6. Дизайн үлгісі — зауыттық әдіс

  • Оқу мақсаттары
  • Бастау
  • Зауыттық әдісті қалай қолдануға болады?
  • Шығару

7. Дизайн үлгісі — Итератор

  • Use Case
  • Бастау
  • Итератор үлгісі әрекетте
  • Шығару

8. Дизайн үлгісі — Медиатор

  • Use Case
  • Оқу мақсаттары
  • Бастау
  • Негізгі әдістен медиатор үлгісін қалай қолдануға болады

9. Дизайн үлгісі — бақылаушы

  • Use Case
  • Оқу мақсаттары
  • Бастау
  • Бақылаушы үлгісін қалай қолдануға болады?
  • Шығару

10. Advance Property Pattern C# 8.0

  • Бастайық
  • Жаңа қосқыш синтаксисі бар үлгіні сәйкестендіру бағдарламасы
  • Сынақ бағдарламасы
  • Консоль шығысы

11. Дизайн үлгісі — Singleton

  • Оқу мақсаттары
  • Бастау
  • Шығару
  • Жіп қауіпсіздігі

Дизайн үлгісі — абстрактілі фабрика

Төрттік банданың пікірінше, абстрактілі зауыттық үлгілерді фабрикалар құру зауыты ретінде қарастыруға болады.


Оқу мақсаттары

  • Абстрактілі зауыттық дизайн үлгісі қандай?
  • Абстрактілі зауыттық дизайн үлгісін пайдаланып кодты қалай жазуға болады?
  • Зауыт провайдерін қалай құруға болады?
  • Зауыттық провайдерді пайдаланатын клиенттік қосымшаны (Негізгі әдістен) қалай жасауға болады

Алғы шарттар

Абстрактілі зауыт үлгісі таза кеңейту зауыттық әдісі болып табылады; дерексіз зауыт дизайнын түсінбес бұрын зауыттық әдіспен өту ұсынылады.

  • OOPS тұжырымдамалары туралы негізгі білім.
  • Кез келген бағдарламалау тілін білу.

Бастау

Жинақ және Ағымдағы шоттар сияқты шот түрлері бар кез келген Банктің бірдей мысалын қарастырайық. Енді абстрактілі зауыттық дизайн үлгісін пайдаланып жоғарыдағы мысалды жүзеге асырайық.


Біріншіден, ISavingAccount және ICurrentAccount интерфейстерін келесідей орындаңыз:


 public interface ISavingAccount{ } public interface ICurrentAccount{ }


Төмендегі сыныптардағы интерфейсті мұраға алыңыз


 public class CurrentAccount : ICurrentAccount { public CurrentAccount(string message) { Console.WriteLine(message); } } public class SavingsAccount : ISavingAccount { public SavingsAccount( string message) { Console.WriteLine(message); } }


Әрбір тіркелгі түрі үшін дерексіз әдістермен дерексіз класс жазайық.


 public abstract class AccountTypeFactory { public abstract ISavingAccount SavingAccountFactory(string message); public abstract ICurrentAccount CurrentAccountFactory(string message); }


Енді дерексіз әдістерді енгізуді қамтамасыз ететін «Bank1Factory» атты зауыттық іске асыруды жасайық.


 public class Bank1Factory : AccountTypeFactory { public override ICurrentAccount CurrentAccountFactory(string message) { return new CurrentAccount(message); } public override ISavingAccount SavingAccountFactory(string message) { return new SavingsAccount(message); } }


Дерексіз зауыттық дизайн үлгісі зауыттық әдіспен ерекшеленеді, ол зауыттық жеткізушіні жүзеге асыру қажет, ол зауыттарды анықтамаға сәйкес қайтарады.


Қазір бізде барлық абстракциялар мен зауыттар бар. Зауыт провайдерін жобалауға рұқсат етіңіз. Төменде зауыт провайдеріне арналған код үзіндісін табыңыз, мұнда статикалық әдіс тіркелгі атауына негізделген зауыт жасайды.


 public class AccountFactoryProvider { public static AccountTypeFactory GetAccountTypeFactory(string accountName) { if (accountName.Contains("B1")) { return new Bank1Factory(); } else return null; } }

Абстрактілі зауыт провайдерін қалай пайдалануға болады?

Есептік жазбаның атауы тура мағынасында “ B1 ” тұратын болса, ол зауыт провайдері арқылы қайтарылған Bank1Factory данасын пайдаланатын шот нөмірлерінің тізімін мысалға алайық.

 static void Main(string[] args) { List<string> accNames = new List<string> { "B1-456", "B1-987", "B2-222" }; for (int i = 0; i < accNames.Count; i++) { AccountTypeFactory anAbstractFactory = AccountFactoryProvider.GetAccountTypeFactory(accNames[i]); if (anAbstractFactory == null) { Console.WriteLine("Invalid " + (accNames[i])); } else { ISavingAccount savingAccount = anAbstractFactory.SavingAccountFactory("Hello saving"); ICurrentAccount currentAccount = anAbstractFactory.CurrentAccountFactory("Hello Current"); } } Console.ReadLine(); }


Егер тіркелгі атауында "B1" литералы болмаса, бағдарлама жарамсыз {{accountName}} мәнін шығарады.

Шығару

Жоғарыдағы код үзіндісінің шығысын төменде табыңыз.


 Hello saving B1-456 Hello Current B1-456 Hello saving B1-987 Hello Current B1-987

Дизайн үлгісі — адаптер

Gang of Four бойынша, адаптер үлгісі класс интерфейстерін клиент қажет ететін интерфейстерге түрлендіреді.


Басқаша айтқанда, адаптердің дизайн үлгісі үйлесімсіз интерфейстердің бірлесіп жұмыс істеуіне көмектеседі.

Use Case

Екі ұйымның бірігуінің мысалын қарастырайық; X ұйымы Y-ді басып алады, бірақ кодты біріктіру кезінде интерфейстер үйлесімді емес. Y ұйымының транзакцияларының тізімін беретін интерфейс X-пен үйлесімді емес деп есептейік.


Осылайша, адаптер дизайнының үлгісі іске асырылуы өте қарапайым болатын бұл мәселені шешуге көмектеседі.

Оқу мақсаттары

  • Адаптердің дизайн үлгісін пайдаланып кодты қалай жасауға болады?

Бастау

X ұйымының клиенттік қолданбасы талап ететін үлгілерге түрлендірілетін Y ұйымынан транзакциялар тізімін жасайық. Жоғарыда аталған сынып «Адаптеуші» ретінде белгілі.


 public class OrgYTransactions { public List<string> GetTransactionsList() { List<string> transactions = new List<string>(); transactions.Add("Debit 1"); transactions.Add("Debit 2"); transactions.Add("Debit 3"); return transactions; } }


Екіншіден, мақсатты интерфейсті жасайық.


 public interface ITransactions{ List<string> GetTransactions(); }


Енді, ең соңында, адаптер класын келесідей іске асырамыз.


 public class TransAdapter : OrgYTransactions, ITransactions { public List<string> GetTransactions() { return GetTransactionsList(); } }


Жоғарыда көрсетілген барлық іске асырулар орындалғаннан кейін консольдық қосымшада адаптер класын қалай пайдалану керектігін түсінейік.


 class Program { static void Main(string[] args) { ITransactions adapter = new TransAdapter(); foreach (var item in adapter.GetTransactions()) { Console.WriteLine(item); } } }


Төмендегі пайдалануды мұқият қарасаңыз, біз үшінші тарап класының OrgYTransactions интерфейстерінің қалай көрінетінін ескермей, ITransactions мақсатты интерфейсін және TransAdapter адаптер класын пайдаландық. Бұл адаптер дизайн үлгісінің күші, ол класс интерфейстерін клиент қажет ететін интерфейстерге түрлендіреді.

Дизайн үлгісі — құрылысшы

Bang of Four пікірінше, «Құрылысшы» жасампаздық үлгісі бір нәрсені құрудың белгілі бір әдісін бөліп, қайта пайдалануға мүмкіндік береді.


Use Case

Автокөліктің мысалын алайық, ал пайдаланушы екі үлгіні, яғни жол талғамайтын көлік пен седан құрастырғысы келді.


Құрылысшы дизайны үлгісі жоғарыда көрсетілген пайдалану жағдайында ыңғайлы болады және қадамдық демонстрацияны көрейік.


Car класының келесі қасиеттері бар.

 public class Car{ public string Name { get; set; } public double TopSpeed { get; set; } public bool IsSUV { get; set; } }

Оқу мақсаттары

  • Құрылысшы дизайн үлгісін пайдаланып кодты қалай жасауға болады?

Бастау

Біріншіден, пайдалану жағдайына сәйкес жол талғамайтын көліктер немесе седандар сияқты әртүрлі автомобиль үлгілері арқылы кеңейтілген дерексіз класс құрастырушысын іске асырайық.


 public abstract class CarBuilder { protected readonly Car _car = new Car(); public abstract void SetName(); public abstract void SetSpeed(); public abstract void SetIsSUV(); public virtual Car GetCar() => _car; }


Абстрактілі класс келесі әдістерден тұрады

  • Car класының әрбір қасиетінің дерексіз әдістері.
  • Car класс данасын шығаратын виртуалды әдіс.


Енді әртүрлі автомобиль үлгілерін жасау үшін CarBuilder сыныбын қолданатын және жасалған көлік данасын қайтаратын зауыт құрайық.


 public class CarFactory { public Car Build(CarBuilder builder) { builder.SetName(); builder.SetSpeed(); builder.SetIsSUV(); return builder.GetCar(); } }


Соңында, автомобильдердің әртүрлі үлгілерін іске асырыңыз.

ModelSuv.cs

 public class ModelSuv : CarBuilder { public override void SetIsSUV() { _car.IsSUV = true; } public override void SetName() { _car.Name = "Maruti SUV"; } public override void SetSpeed() { _car.TopSpeed = 1000; } }

ModelSedan.cs

 public class ModelSedan : CarBuilder { public override void SetIsSUV() { _car.IsSUV = false; } public override void SetName() { _car.Name = "Maruti Sedan"; } public override void SetSpeed() { _car.TopSpeed = 2000; } }

Main() әдісінен құрастырушы үлгісін қалай қолдану керек

Соңында, factory.Build(<model>) әдісінің көмегімен әртүрлі автомобиль үлгілерін құрастыру үшін дизайн үлгілерін қолданайық.


 static void Main(string[] args) { var sedan = new ModelSedan(); var suv = new ModelSuv(); var factory = new CarFactory(); var builders = new List<CarBuilder> { suv, sedan }; foreach (var b in builders) { var c = factory.Build(b); Console.WriteLine($"The Car details" + $"\n--------------------------------------" + $"\nName: {c.Name}" + $"\nIs SUV: {c.IsSUV}" + $"\nTop Speed: {c.TopSpeed} mph\n"); } }

Жоғарыдағы қолдану құрылысшы дизайн үлгісін пайдаланып әртүрлі көлік үлгілерін қаншалықты әдемі құрастыра алатынымызды көрсетеді.


Код үлгісі жоғары қолдауға және кеңейтуге болады. Болашақта бізге жаңа үлгіні әзірлеу қажет болса, тек жаңа модель CarBuilder класын кеңейту керек және ол аяқталды.

Шығару

Жауапкершілік үлгісін қалай пайдалануға болады

Bang of Four пікірінше, ол сұрауды өңдеу үшін жауапкершілік тізбегін анықтайды. Басқаша айтқанда, сұрауды бір нысаннан екіншісіне нысан өз жауапкершілігін қабылдағанға дейін жіберіңіз.


Use Case

Кез келген корпоративтік компаниядағы шағымдар жүйесінің мысалын қарастырайық. Мұнда және кім бекітетін баға диапазонының тізімі берілген.


 100–1000 Rs => Junior/Senior Engineers => Approved by Manager 1001–10000 Rs => Managers => Approved by Senior Manager


Егер сома 10 000 ауқымынан тыс болса, аға менеджерден ерекше мақұлдау қажет.


Жоғарыда келтірілген пайдалану жағдайын Жауапкершілік тізбегі дизайн үлгісі арқылы оңай жүзеге асыруға болады. Сонымен, шағым класы келесі қасиеттерге ие.


 public class Claim{ public int Id{get;set;} public double amount{get;set;} }

Бастау

Біріншіден, шағымды мақұлдаушы қандай функцияларды орындай алатынын анықтап алайық және әртүрлі деңгейдегі қызметкерлер үшін иерархияны орнатайық. Төменде көрсетілгендей дерексіз классты орындаңыз


 public abstract class ClaimApprover { protected ClaimApprover claimApprover; public void SetHierarchy(ClaimApprover claimApprover) { this.claimApprover = claimApprover; } public abstract void ApproveRequest(Claim claim); }


Қолдану жағдайына сәйкес, «кіші/аға» сыныбын талап етушіге көшейік. Қызметкерлердің бұл сыныбы/тағайындауы ешқандай шағымдарды бекіте алмайтынын ескеріңіз.


 public class Junior : ClaimApprover { public override void ApproveRequest(Claim claim) { System.Console.WriteLine("Cannot approve"); } }


Сол сияқты, менеджер және аға менеджер рөлдері үшін іске асыруды анықтайық.


 public class Manager : ClaimApprover { public override void ApproveRequest(Claim claim) { if (claim.amount >= 100 && claim.amount <= 1000) { System.Console.WriteLine($"Claim reference {claim.Id} with amount {claim.amount} is approved by Manager"); } else if (claimApprover != null) { claimApprover.ApproveRequest(claim); } } }


Сома ауқымына негізделген, егер Менеджер ауқымында болса, шағымды Менеджер мақұлдауы мүмкін екенін ескеріңіз; әйтпесе, сұрау Аға менеджерге жіберіледі.


 public class SeniorManager : ClaimApprover { public override void ApproveRequest(Claim claim) { if (claim.amount > 1000 && claim.amount <= 10000) { System.Console.WriteLine($"Claim reference {claim.Id} with amount {claim.amount} is approved by Senior Manager"); } else { System.Console.WriteLine($"Exceptional approval for Claim reference {claim.Id} with amount {claim.amount} is approved by Senior Manager"); } } }


Сол сияқты, егер сома ауқымы Аға менеджер ауқымында болса, шағымды Менеджер мақұлдай алады; әйтпесе, иерархияның соңғысы болғандықтан, ауқымнан тыс сома үшін ерекше бекіту орындалады.


 ClaimApprover junior = new Manager(); ClaimApprover sukhpinder = new Manager(); ClaimApprover singh = new SeniorManager(); junior.SetHierarchy(sukhpinder); sukhpinder.SetHierarchy(singh); Claim c1 = new Claim() { amount = 999, Id = 1001 }; Claim c2 = new Claim() { amount = 10001, Id = 1002 }; junior.ApproveRequest(c1); sukhpinder.ApproveRequest(c2);

Жауапкершілік үлгісін қалай пайдалануға болады?

  1. Шағымды мақұлдаушыны анықтаңыз: кіші, бірақ ол ешқандай шағымды мақұлдай алмайды.
  2. Шағымды мақұлдаушыны анықтаңыз: менеджер «сухпиндер».
  3. Шағымды растаушыны анықтаңыз: «Сингх» аға менеджері.
  4. Кіші сынып үшін иерархиялық қатынас орнатыңыз, яғни шағымдарды мақұлдаушы менеджер болып табылады.
  5. Менеджер үшін иерархиялық қатынасты орнатыңыз, яғни шағымдарды мақұлдаушы аға менеджер болып табылады.
  6. Шағымдардың екі түрлі ауқымын жасаңыз.
  7. Кіші менеджерге шағым сұрауын жібереді.
  8. Менеджер шағым сұрауын аға менеджерге жібереді.

Шығару

 Claim reference 1001 with amount 999 is approved by Manager Exceptional approval for Claim reference 1002 with amount 10001 is approved by Senior Manager


1-жолдың шығысы үшін сома ауқымда болды, сондықтан менеджер оны бекітті.


2-жолдың шығысы үшін, аға менеджер оны мақұлдағанымен, сома ауқымнан тыс болды.

Дизайн үлгісі — Декоратор

Gang of Four пікірінше, үлгі сынып нысанына динамикалық түрде қосымша жауапкершіліктер қосады.


Use Case

Құны он миллион тұратын көлікті сатып алу мысалын қарастырайық; компания келесі қосымша мүмкіндіктерді ұсынады.

  • Люк
  • Жетілдірілген музыка жүйесі
  • және тағы басқалар


Кейбір қосымша мүмкіндіктермен автомобильдің жалпы бағасы артады. Жоғарыдағы пайдалану жағдайын Декоратор үлгісін қолданып жүзеге асырайық.

Оқу мақсаттары

  • Декоратор дизайны үлгісін пайдаланып кодты қалай жасауға болады?

Бастау

Жоғарыда анықталған пайдалану жағдайын жүзеге асырайық. Біріншіден, абстрактілі Car класын және оның негізгі әдістерін анықтаңыз.


 public abstract class Car{ public abstract int CarPrice(); public abstract string GetName(); }


Автокөлік абстрактілі класынан жоғары орналасқан шағын көлікті қарастырайық.


 public class SmallCar : Car{ public override int CarPrice() => 10000; public override string GetName() => "Alto Lxi"; }


Енді Car компонентін пайдаланып CarDecorator класын іске асырыңыз.


 public class CarDecorator : Car { protected Car _car; public CarDecorator(Car car) { _car = car; } public override int CarPrice() => _car.CarPrice(); public override string GetName() =>_car.GetName(); }


Енді CarDecorator сыныбын иемденетін Автокөлік үшін қолжетімді әрбір қосымша мүмкіндік үшін бөлек класс жасайық.


Қолдану жағдайына сәйкес, қосымша мүмкіндіктер люк пен жетілдірілген музыка жүйесі болып табылады.

AdvanceMusic.cs

Әдістерді қайта белгілеңіз

  • Автокөліктің жалпы бағасына «Жетілдірілген музыкалық жүйенің» қосымша құнын қосыңыз.

  • Көлік атауын қосымша функция атауымен жаңартыңыз.

     public class AdvanceMusic : CarDecorator { public AdvanceMusic(Car car) : base(car) { } public override int CarPrice() => _car.CarPrice() + 3000; public override string GetName()=> "Alto Lxi with advance music system"; }

Люк. cs

Әдістерді қайта белгілеңіз

  • Автокөліктің жалпы бағасына «люктің» қосымша құнын қосыңыз.
  • Көлік атауын қосымша функция атауымен жаңартыңыз.
 public class Sunroof : CarDecorator { public Sunroof(Car car) : base(car) { } public override int CarPrice() => _car.CarPrice() + 2000; public override string GetName() => "Alto Lxi with Sunroof"; }

Декоратор үлгісі әрекетте

SmallCar данасын жасаңыз және көліктің атауы мен бағасын шығарыңыз.


 Car car = new SmallCar(); Console.WriteLine($"Price of car {car.GetName()} : " + car.CarPrice());


Енді төменде көрсетілгендей қосымша мүмкіндіктерді қосамыз


 var car1 = new Sunroof(car); var car2 = new AdvanceMusic(car);

Толық код

 static void Main(string[] args) { Car car = new SmallCar(); Console.WriteLine($"Price of car {car.GetName()} : " + car.CarPrice()); var car1 = new Sunroof(car); Console.WriteLine($"Price of car {car1.GetName()} : " + car1.CarPrice()); var car2 = new AdvanceMusic(car); Console.WriteLine($"Price of car {car2.GetName()} : " + car2.CarPrice()); }

Шығару

Құттықтаймын..!! Декоратор үлгісін пайдаланып пайдалану жағдайын сәтті орындадыңыз.

Дизайн үлгісі — зауыттық әдіс

«Төрттік тобына» сәйкес, зауыттық әдіс ішкі сыныпқа қандай сынып объектісін жасау керектігін анықтауға мүмкіндік береді.


Оқу мақсаттары

  • Зауыттық әдісті жобалау үлгісі қандай?
  • Зауыттық әдіспен кодты қалай жазуға болады?

Бастау

Жинақ және Ағымдағы шоттар сияқты шот түрлері бар кез келген банктің мысалын қарастырайық. Енді жоғарыдағы мысалды зауыттық дизайн үлгісін қолдана отырып жүзеге асырайық


Біріншіден, тіркелгі түріндегі дерексіз класс жасаңыз.


 public abstract class AccoutType { public string Balance { get; set; } }


Төменде көрсетілгендей AccountType дерексіз сыныбын иеленетін ағымдағы және сақтау шотының сыныптарын енгізіңіз.


 public class SavingsAccount : AccoutType { public SavingsAccount() { Balance = "10000 Rs"; } } public class CurrentAccount : AccoutType { public CurrentAccount() { Balance = "20000 Rs"; } }


Соңында, класс нысанын жасауға көмектесетін келісім-шартты қамтамасыз ететін зауыттық интерфейсті іске асырамыз. Бұл интерфейс Жаратушы ретінде де белгілі.


 public interface IAccountFactory { AccoutType GetAccoutType(string accountName); }


Соңында, төменде көрсетілгендей жасаушы интерфейсі әдісінің орындалуын жазыңыз. Жасаушыны іске асыратын класс Concrete Creator ретінде белгілі.


 public class AccountFactory : IAccountFactory { public AccoutType GetAccoutType(string accountName) { if (accountName.Equals("SAVINGS", StringComparison.OrdinalIgnoreCase)) { return new SavingsAccount(); } else if (accountName.Equals("CURRENT", StringComparison.OrdinalIgnoreCase)) { return new CurrentAccount(); } else { throw new ArgumentException("Invalid account name"); } } }


Міне бітті. Банк үлгісін пайдаланып зауыттық әдісті сәтті енгіздіңіз.

Зауыттық әдісті қалай қолдануға болады?

Қосалқы сынып тіркелгі атауына негізделген қандай «AccountType» сынып нысаны жасалатынын шешеді.


 class Program { static void Main(string[] args) { IAccountFactory accountFactory = new AccountFactory(); var savingAccount = accountFactory.GetAccoutType("SAVINGS"); Console.WriteLine("Saving account balance: " + savingAccount.Balance); var currentAccount = accountFactory.GetAccoutType("CURRENT"); Console.WriteLine("Current account balance: " + currentAccount.Balance); } }

Мысалы, егер тіркелгі атауы «SAVINGS» болса, «SavingAccount» сыныбының нысаны жасалады және қайтарылады.


Сол сияқты, егер тіркелгі атауы «CURRENT» болса, «CurrentAccount» сыныбының нысаны жасалады және қайтарылады.

Шығару

 Saving account balance: 10000 Rs Current account balance: 20000 Rs

Дизайн үлгісі — Итератор

Gang of Four пікірінше, итератор үлгісі агрегатор нысанын оның орындалуын білмей алу процесін қамтамасыз етеді.


Use Case

Автокөліктердің коллекциялық тізімін және string[] мотоциклдер массивінің мысалын алайық, біз жиынтықты оның тізім немесе массив екенін білмей қайталай алатындай етіп құрастыруымыз керек.


Итератор дизайн үлгісі стандартты итератор әртүрлі жинақ түрлерін аралайтын осы мәселені шешуге көмектеседі.

Бастау

Жоғарыдағы пайдалану жағдайын қарастыра отырып, тізім мен массив итераторы үстінде дерексіз қабат ретінде әрекет ететін пайдаланушы итератор интерфейсін анықтайық.


 public interface IVehicleIterator{ void First(); bool IsDone(); string Next(); string Current(); }


Енді пайдалану жағдайына сәйкес жоғарыдағы интерфейсті жүзеге асыратын автомобиль және мотоцикл итераторларын жазыңыз.

CarIterator.cs

 public class CarIterator : IVehicleIterator { private List<string> _cars; private int _current; public CarIterator(List<string> cars) { _cars = cars; _current = 0; } public string Current() { return _cars.ElementAt(_current); } public void First() { _current = 0; } public bool IsDone() { return _current >= _cars.Count; } public string Next() { return _cars.ElementAt(_current++); } }


Автокөлік итераторы List<string> жиыны арқылы жүзеге асырылады және интерфейс әдістерін жүзеге асыруды қамтамасыз етеді.

MotorcycleIterator.cs

Мотоцикл итераторы string[] жинағы арқылы жүзеге асырылады және интерфейс әдістерін іске асыруды қамтамасыз етеді.


 public class MotercycleIterator : IVehicleIterator { private string[] _motercylces; private int _current; public MotercycleIterator(string[] motercylces) { _motercylces = motercylces; _current = 0; } public string Current() { return _motercylces[_current]; } public void First() { _current = 0; } public bool IsDone() { return _current >= _motercylces.Length; } public string Next() { return _motercylces[_current++]; } }


Жоғарыда аталған барлық иераторлар анықталғаннан кейін итераторларды жасайтын стандартты агрегатор нысан интерфейсін анықтаңыз.


 public interface IVehicleAggregate{ IVehicleIterator CreateIterator(); }


Соңында, жоғарыдағы агрегатор интерфейсін жүзеге асыратын сыныптарды жазыңыз. Қолдану жағдайына сәйкес, автомобиль және мотоцикл сыныптары агрегатор интерфейсін жүзеге асырады.

Автокөлік. cs

Агрегатор интерфейсінің әдісі төменде көрсетілгендей сәйкес итераторды қайтарады.


 public class Car : IVehicleAggregate { private List<string> _cars; public Car() { _cars = new List<string> { "Car 1", "Car 2", "Car 3" }; } public IVehicleIterator CreateIterator() { return new CarIterator(_cars); } }

Мотоцикл. cs

Агрегатор интерфейсінің әдісі төменде көрсетілгендей сәйкес итераторды қайтарады.


 public class Motercycle : IVehicleAggregate { private string[] _motercycles; public Motercycle() { _motercycles = new[] { "Bike 1", "Bike 2", "Bike 3" }; } public IVehicleIterator CreateIterator() { return new MotercycleIterator(_motercycles); } }

Итератор үлгісі әрекетте

PrintVehicles әдістері !iterator.isDone, содан кейін жинақ элементін шығаратынын тексереді. Қандай жинақпен айналысатынымызға қарамастан, First, IsDone және Next сияқты әдістерді орындаңыз.


 static void Main(string[] args) { IVehicleAggregate car = new Vehicles.Car(); IVehicleAggregate motercycle = new Vehicles.Motercycle(); IVehicleIterator carIterator = car.CreateIterator(); IVehicleIterator motercycleIterator = motercycle.CreateIterator(); PrintVehicles(carIterator); PrintVehicles(motercycleIterator); } static void PrintVehicles(IVehicleIterator iterator) { iterator.First(); while (!iterator.IsDone()) { Console.WriteLine(iterator.Next()); } }

Шығару

Біз жинақтың негізгі түрін білмейміз, бірақ ол әлі де Итератор дизайн үлгісі арқылы қайталанады. Жалғастырып, іске қоссаңыз, ол келесі нәтижені көрсетеді.

Дизайн үлгісі — делдал

Gang of Four пікірінше, Медиатор үлгісі объектінің бір-бірімен әрекеттесуін инкапсуляциялайды.


Медиаторды жобалау үлгісі бізге объектінің өзара әрекеттесуін инкапсуляциялау арқылы еркін байланысқан қолданбаларды жобалауға көмектеседі.

Use Case

Қатысушылар тіркелетін сөйлесу бөлмесінің мысалын және қалай тиімді байланысуға болатынын қарастырайық.


Медиатор дизайн үлгісін пайдаланып келесі сөйлесу бөлмесін енгізу қажет.


 David to Scott: 'Hey' Scott to David: 'I am good how about you.' Jennifer to Ashley: 'Hey ashley... david is back in the group' Jennifer to David: 'Where have you been?' Ashley to David: 'How come you aren't active here anymore?'

Оқу мақсаттары

  • Медиатор дизайн үлгісін пайдаланып кодты қалай жасауға болады?

Бастау

Негізгі қадам - сөйлесу бөлмесінде пайдаланылатын пайдаланушы аттары тізімін жасау. Бұл үшін жалпы тізім төменде көрсетілген.


 public enum Username{ Ashley, David, Jennifer, Scott }


Енді, ең алдымен, сөйлесу бөлмесінің абстрактілі қабатын іске асырыңыз.


 public abstract class AChatroom { public abstract void Register(User user); public abstract void Post(string fromUser, string toUser, string msg); }


Және абстрактілі әдістерді анықтайтын класс. Әдістер пайдаланушының сөздікте бар-жоғын растайды. Мысалы, тіркеу әдісі пайдаланушының бұрыннан бар-жоғын тексереді. Егер жоқ болса, пайдаланушыны сөйлесу бөлмесінде ғана тіркеңіз.


 public class Chatroom : AChatroom { private Dictionary<string, User> _users = new Dictionary<string, User>(); public override void Post(string fromUser, string toUser, string msg) { User participant = _users[toUser]; if (participant != null) { participant.DM(fromUser, msg); } } public override void Register(User user) { if (!_users.ContainsValue(user)) { _users[user.Name] = user; } user.Chatroom = this; } }


Соңында, сөйлесу бөлмесінде пайдаланушыға хабарлама жіберу немесе басқа пайдаланушыдан хабарлама алу сияқты пайдаланушы орындай алатын әрекеттерді орындайық.


 public class User { private Chatroom _chatroom; private string _name; public User(string name) => this._name = name; public string Name => _name; public Chatroom Chatroom { set { _chatroom = value; } get => _chatroom; } public void Post(string to, string message) => _chatroom.Post(_name, to, message); public virtual void DM(string from, string message) => Console.WriteLine("{0} to {1}: '{2}'", from, Name, message); }

Негізгі әдістен медиатор үлгісін қалай пайдалануға болады

 static void Main(string[] args) { Chatroom chatroom = new Chatroom(); User Jennifer = new UserPersona(Username.Jennifer.ToString()); User Ashley = new UserPersona(Username.Ashley.ToString()); User David = new UserPersona(Username.David.ToString()); User Scott = new UserPersona(Username.Scott.ToString()); chatroom.Register(Jennifer); chatroom.Register(Ashley); chatroom.Register(David); chatroom.Register(Scott); David.Post(Username.Scott.ToString(), "Hey"); Scott.Post(Username.David.ToString(), "I am good how about you."); Jennifer.Post(Username.Ashley.ToString(), "Hey ashley... david is back in the group"); Jennifer.Post(Username.David.ToString(), "Where have you been?"); Ashley.Post(Username.David.ToString(), "How come you aren't active here anymore?"); Console.ReadKey(); }


  1. Чат бөлмесі сыныбының нысаны жасалды.
  2. Бірегей атаулармен төрт түрлі пайдаланушы жасалады.
  3. Олардың әрқайсысын сөйлесу бөлмесінде тіркеңіз.
  4. Енді пайдаланушылар бір-біріне хабарламалар жібере алады.

Бағдарламаның орындалуы тек пайдаланушы класының Post әдісін сипаттайды.


Шығару: Жоғарыдағы бағдарламаның орындалуының чат бөлмесінің тарихы


 David to Scott: 'Hey' Scott to David: 'I am good how about you.' Jennifer to Ashley: 'Hey ashley... david is back in the group' Jennifer to David: 'Where have you been?' Ashley to David: 'How come you aren't active here anymore?'

Дизайн үлгісі — бақылаушы

Gang of Four сәйкес, бақылаушы үлгісі екі немесе одан да көп нысандарға тәуелділікті анықтайды. Сонымен, бір нысан күйі өзгерген кезде оның барлық тәуелділері хабарланады.


Басқаша айтқанда, бір нысандағы өзгеріс басқа нысандағы хабарландыруды бастайды.

Use Case

Жазушыларының « x » саны бар Instagram атақты ықпал етушісінің мысалын алайық. Осылайша, атақты адам жазба қосқан сәтте, барлық жазылушыларға хабарланады.


Жоғарыда аталған қолдану жағдайын Observer Design Pattern көмегімен жүзеге асырайық.

Оқу мақсаттары

  • Бақылаушы дизайн үлгісін пайдаланып кодты қалай жасауға болады?

Бастау

Пайдалану жағдайына сәйкес, бірінші атақты адам орындай алатын әрекеттерді қамтитын интерфейсті жүзеге асырады. Ол « Тақырып » ретінде белгілі.


 public interface ICelebrityInstagram{ string FullName { get; } string Post { get; set; } void Notify(string post); void AddFollower(IFollower fan); void RemoveFollower(IFollower fan); }

Тақырып келесі мүше функцияларын қамтиды.

  • Хабарландыру: барлық жазылушыларды хабардар ету.

  • AddFollower: атақтылар тізіміне жаңа жазылушы қосыңыз.

  • RemoveFollower: атақтылар тізімінен жазылушыны алып тастаңыз.


Енді хабарландыру үшін «Жаңарту» мүше функциясын қамтитын бақылаушы «IFollower» интерфейсін іске қосыңыз.


 public interface IFollower{ void Update(ICelebrityInstagram celebrityInstagram); }


Ақырында, « Тақырып » және « Байқаушы » үшін де «Нақты іске асыруды» жүзеге асыру уақыты келді.

ConcreteObserver аты «Follower.cs»

Ол консольге атақты адамның атын және жазбасын шығаратын Жаңарту мүшесі функциясының орындалуын қамтамасыз етеді.


 public class Follower : IFollower { public void Update(ICelebrityInstagram celebrityInstagram) { Console.WriteLine($"Follower notified. Post of {celebrityInstagram.FullName}: " + $"{celebrityInstagram.Post}"); } }

Нақты тақырып «Сухпиндер. cs»

 public class Sukhpinder : ICelebrityInstagram { private readonly List<IFollower> _posts = new List<IFollower>(); private string _post; public string FullName => "Sukhpinder Singh"; public string Post { get { return _post; } set { Notify(value); } } public void AddFollower(IFollower follower) { _posts.Add(follower); } public void Notify(string post) { _post = post; foreach (var item in _posts) { item.Update(this); } } public void RemoveFollower(IFollower follower) { _posts.Remove(follower); } }

Бақылаушы үлгісін қалай анықтауға болады?

Келесі пайдалану жағдайы төменде көрсетілген мәлімдеме орындалған сайын sukhpinder.Post = “Мен дизайн үлгілерін жақсы көремін.”; Жаңарту әдісі әрбір жазылушы үшін іске қосылады, яғни әрбір ізбасар нысаны «Sukhpinder» жаңа жазбасы туралы ескертіледі.


 static void Main(string[] args) { var sukhpinder = new Sukhpinder(); var firstFan = new Follower(); var secondFan = new Follower(); sukhpinder.AddFollower(firstFan); sukhpinder.AddFollower(secondFan); sukhpinder.Post = "I love design patterns."; Console.Read(); }

Шығару

Advance сипат үлгісі C# 8.0

Мақалада үлгіні сәйкестендіру бастапқы жүйенің бөлігі болып табылмайтын пішіндердегі деректерді пайдалану және өңдеудің тиімді жолын қалай қамтамасыз ететінін сипаттайды.


Бастайық

Төлем калькуляторының мысалын алайық және үлгіні сәйкестендіру алгоритмді жазуға қалай көмектесетінін көрейік.

Мақалада пайдаланылған нысан класы

 public class Car { public int PassengerCount { get; set; } } public class DeliveryTruck { public int Weight { get; set; } } public class Taxi { public int Fare { get; set; } } public class Bus { public int Capacity { get; set; } public int RidersCount { get; set; } }


1-мысал: Төмендегі шарттарға сәйкес жол ақысын есептеңіз:


  • Егер көлік автомобиль болса => 100 Rs
  • Егер көлік DeliveryTruck болса => 200 Rs
  • Көлік автобус болса => 150 Rs
  • Көлік такси болса => 120 руб

Жаңа ауысу синтаксисі бар үлгіні сәйкестендіру бағдарламасы

Көлік түрі Car 100-ге сәйкес келсе, қайтарылады және т.б. Нөл және {} нысан түрі үшін әдепкі жағдайлар екенін ескеріңіз.

Сондай-ақ, «_» әдепкі сценарийді бағдарламалау үшін пайдаланылуы мүмкін. Жаңа қосқыш синтаксисін қараңыз.


Бұл кодтаудың әлдеқайда таза және тиімді әдісі және коммутатор синтаксисінде бір әріпті айнымалы атауларды пайдалану ұсынылады.


 public static int TollFare(Object vehicleType) => vehicleType switch { Car c => 100, DeliveryTruck d => 200, Bus b => 150, Taxi t => 120, null => 0, { } => 0 };

Жоғарыдағы сынақ бағдарламасы

Консоль қолданбасы тұрғысынан сынақ мысалдары. Төмендегі код жоғарыдағы үлгіні сәйкестендіру функциясын негізгі әдістен қалай шақыру керектігін көрсетеді.


 var car = new Car(); var taxi = new Taxi(); var bus = new Bus(); var truck = new DeliveryTruck(); Console.WriteLine($"The toll for a car is {TollFare(car)}"); Console.WriteLine($"The toll for a taxi is {TollFare(taxi)}"); Console.WriteLine($"The toll for a bus is {TollFare(bus)}"); Console.WriteLine($"The toll for a truck is {TollFare(truck)}");

Консоль шығысы

 The toll for a car is 100 The toll for a taxi is 120 The toll for a bus is 150 The toll for a truck is 200


2-мысал: Көлік түріне қарай тұру бағасын қосыңыз


  • «ЖОҚ» жолаушылары бар автомобильдер мен таксилер қосымша 10 рупий төлейді.
  • Екі жолаушы бар көліктер мен таксилерге 10 рупий жеңілдік беріледі.
  • Үш немесе одан да көп жолаушысы бар автомобильдер мен таксилерге 20 рупийлік жеңілдік беріледі.
  • Жолаушылар саны 50%-дан аз автобустар қосымша 30 рупий төлейді.
  • Жолаушыларының 90%-дан астамы бар автобустар 40 рупий жеңілдік алады.
  • 5000 фунттан асатын жүк көліктерінен қосымша 100 рупий алынады.
  • 3000 фунттан төмен жеңіл жүк көліктеріне 20 рупийлік жеңілдік берілген.

Үлгіні сәйкестендіру қосқышы

Жалғыз және бірнеше сипат кластары бар үлгі сәйкестік синтаксисін қараңыз. Сілтеме

Үлгіні сәйкестендіру — Автокөлік нысаны

 Car { PassengerCount: 0 } => 100 + 10, Car { PassengerCount: 1 } => 100, Car { PassengerCount: 2 } => 100 - 10, Car c => 100 - 20,

Үлгіні сәйкестендіру — Такси нысаны

 Taxi {Fare:0 }=>100+10, Taxi { Fare: 1 } => 100, Taxi { Fare: 2 } => 100 - 10, Taxi t => 100 - 20,

Үлгіні сәйкестендіру — автобус нысаны

 Bus b when ((double)b.RidersCount / (double)b.Capacity) < 0.50 => 150 + 30, Bus b when ((double)b.RidersCount / (double)b.Capacity) > 0.90 => 150 - 40, Bus b => 150,

Үлгі сәйкестігі — Жеткізу көлігі нысаны

 DeliveryTruck t when (t.Weight > 5000) => 200 + 100, DeliveryTruck t when (t.Weight < 3000) => 200 - 20, DeliveryTruck t => 200,

Барлық нысандарды біріктіру

Төмендегі мысал үлгіні сәйкестендірудің артықшылықтарын көрсетеді: үлгі тармақтары ретімен құрастырылған. Сондай-ақ компилятор қол жетімсіз код туралы ескертеді.


 public static int OccupancyTypeTollFare(Object vehicleType) => vehicleType switch { Car { PassengerCount: 0 } => 100 + 10, Car { PassengerCount: 1 } => 100, Car { PassengerCount: 2 } => 100 - 10, Car c => 100 - 20, Taxi { Fare: 0 } => 100 + 10, Taxi { Fare: 1 } => 100, Taxi { Fare: 2 } => 100 - 10, Taxi t => 100 - 20, Bus b when ((double)b.RidersCount / (double)b.Capacity) < 0.50 => 150 + 30, Bus b when ((double)b.RidersCount / (double)b.Capacity) > 0.90 => 150 - 40, Bus b => 150, DeliveryTruck t when (t.Weight > 5000) => 200 + 100, DeliveryTruck t when (t.Weight < 3000) => 200 - 20, DeliveryTruck t => 200, null => 0, { } => 0, };

Жоғарыдағы сынақ бағдарламасы

Консоль қолданбасы тұрғысынан сынақ мысалдары. Төмендегі код жоғарыдағы үлгіні сәйкестендіру функциясын негізгі әдістен қалай шақыру керектігін көрсетеді.


 var car1 = new Car{ PassengerCount=2}; var taxi1 = new Taxi { Fare = 0 }; var bus1 = new Bus { Capacity = 100, RidersCount = 30 }; var truck1 = new DeliveryTruck { Weight = 30000 }; Console.WriteLine($"The toll for a car is {OccupancyTypeTollFare(car1)}"); Console.WriteLine($"The toll for a taxi is {OccupancyTypeTollFare(taxi1)}"); Console.WriteLine($"The toll for a bus is {OccupancyTypeTollFare(bus1)}"); Console.WriteLine($"The toll for a truck is {OccupancyTypeTollFare(truck1)}");

Консоль шығысы

 The toll for a car is 90 The toll for a taxi is 110 The toll for a bus is 180 The toll for a truck is 300


«Үлгілерді сәйкестендіру кодты оқуға ыңғайлы етеді және сыныптарыңызға код қосу мүмкін болмаған кезде объектіге бағытталған әдістерге балама ұсынады.»

Дизайн үлгісі — Singleton

Gang of Four — Singleton дизайн үлгісі белгілі бір сыныптың тек бір данасы/нысаны және жаһандық кіру нүктесі болуын қамтамасыз етеді.


Оқу мақсаттары

  • Синглтон дизайн үлгісін пайдаланып кодты қалай жасауға болады?

Бастау

Синглтондық сыныптар белгілі бір сыныптың бірнеше нысанының данасын жою үшін қолданылады.


 public class SingletonExample { private string Name { get; set; } = "Hello from singleton"; private static SingletonExample _instance; public static SingletonExample Instance { get { if (_instance == null) { _instance = new SingletonExample(); } return _instance; } } public SingletonExample() { } public string GetName() => Name; }

Бөліну

  1. 1-итерация _instance==null тек даналар жасалатынын білдіреді.
  2. 2-итерация, қазіргідей _intance !=null Осылайша бұрын жасалған даналар қайтарылады.

Консольдық қолданбаны пайдаланып сынақ

Синглтон класын екі рет шақырайық және қайтарылған дананы екі түрлі айнымалыға тағайындайық. Соңында, theObject.Equals функциясын пайдаланып екі нысанның тең екенін тексеріңіз.


 static void Main(string[] args) { var response = SingletonExample.Instance; Console.WriteLine(response); var response1 = SingletonExample.Instance; Console.WriteLine(response1); Console.WriteLine(Object.Equals(response1, response)); }
  • Егер ол «true» мәнін қайтарса, бұл әр уақытта бір дананың шығарылатынын білдіреді.
  • Егер ол false мәнін қайтарса, бұл сынып синглтон үлгісіне бағынбайды дегенді білдіреді.

Шығару

Консоль шығысы шын мәнін қайтарады; құттықтаймын. Сіз Singleton үлгісін сәтті енгіздіңіз.



Жіп қауіпсіздігі

Жоғарыда аталған класс синглондық класс ретінде белгілі, бірақ қазіргі уақытта ол ағынмен қауіпсіз емес. Көп ағынды ортада екі ағын if (_instance == null) операторын бір уақытта тигізуі мүмкін және бізде синглондық сыныптың бірнеше даналары болады.


Қауіпсіз ағынның бір жолы - құлыптау механизмін пайдалану, ал екінші жолы - таза және тиімді тәсіл үшін тек оқуға арналған дананы жасау.

 public class ThreadSafeSingleton { private static readonly ThreadSafeSingleton _instance = new ThreadSafeSingleton(); public static ThreadSafeSingleton Instance { get { return _instance; } } public ThreadSafeSingleton() { } }

Github үлгісі

https://github.com/ssukhpinder/DesignPatterns

Оқығаныңызға рахмет!

Демеушілік маған осындай жаңа жобаларды жалғастыруға және құруға көмектеседі.


🙏 Егер сіз Pay, Noticed немесе менің басқа жобаларымның бірін пайдалансаңыз, аздаған үлесіңіз ТҮЛ КӨП дегенді білдіреді. Өздігінен ашық бастапқы код шоттарды төлемейді. Сіздің көмегіңізбен жұмысымды жалғастыру тұрақты болады және мен нақты жұмысқа барудың қажеті жоқ деп үміттенемін 😛.

C# бағдарламалау🚀

C# қауымдастығының бөлігі болғаныңыз үшін рахмет!

Кофе сатып алыңыз

L O A D I N G
. . . comments & more!

About Author

Sukhpinder Singh HackerNoon profile picture
Sukhpinder Singh@ssukhpinder
Programmer by heart | C# | Python | .Net Core | Xamarin | Angular | AWS

ТЕГТЕРДІ АЛУ

БҰЛ МАҚАЛА БАСҚАРҒАН...