Back home

أنماط التصميم من خلال البرامج التعليمية - قوة OOP (الجزء الأول)

رحلة أنماط التصميم - قوة OOP 1

أنماط التصميم من خلال البرامج التعليمية — قوة OOP (الجزء الأول)

المتطلبات الأساسية - تتطلب سلسلة المدونات هذه مستوى متوسطًا من الخبرة في البرمجة الموجهة للكائنات. يجب أن تكون لديك معرفة أساسية بالفئة والكائن والمنشئ والميراث والقيمة ونوع المرجع. سوف يكتسب المستوى المتوسط ​​المعرفة وسيعمل الخبراء على صقل معرفته من خلال قراءة هذه السلسلة من البداية إلى النهاية. المتطلبات الأساسية - تتطلب سلسلة المدونات هذه خبرة متوسطة في البرمجة الموجهة للكائنات. يجب أن يكون لديك فهم أساسي للفئات والكائنات والمنشئات والميراث والقيمة وأنواع المراجع. سوف يكتسب الوسيط المعرفة وسيعمل الخبير على صقل معرفته بقراءة هذه السلسلة من البداية إلى النهاية.

تُستخدم أنماط التصميم لتمثيل أفضل الممارسات التي يتبناها مجتمع مطوري البرامج الموجهة للكائنات ذوي الخبرة. تُستخدم أنماط التصميم لتمثيل أفضل الممارسات التي يتبناها مجتمع من مطوري البرامج الموجهة للكائنات ذوي الخبرة.

يساعدنا نمط تصميم المنشئ على بناء كائن بطريقة أكثر بساطة وقابلية للقراءة. يتبع نمط تصميم المنشئ قاعدتين بسيطتين كما هو مذكور أدناه. يساعدنا نمط تصميم المنشئ على بناء الكائنات بطريقة أبسط وسهلة القراءة. يتبع نمط تصميم المنشئ قاعدتين بسيطتين، كما هو موضح أدناه.

  1. فصل التمثيل الطبقي الأصلي وطرق بنائه. افصل بين تمثيل الفئة الأصلية ومنشئها.

  2. قم بإرجاع مثيل الفصل في الخطوة الأخيرة قم بإرجاع مثيل للفئة في الخطوة الأخيرة

أفضل مثال على نمط التصميم المنشئ هو SwiftUI، نعم لقد قرأت بشكل صحيح. يستخدم SwiftUI نمط تصميم منشئ لمعظم فئاته، على سبيل المثال. نص، صورة أفضل مثال على نمط تصميم المنشئ هو SwiftUI، نعم لقد قرأت ذلك بشكل صحيح. تستخدم معظم الفئات في SwiftUI نمط التصميم المنشئ، مثل النصوص والصور وما إلى ذلك.

مشكلة: سؤال:

فكر في الفئة، على سبيل المثال، الشخص الذي يمتلك عشر خصائص أو أكثر، وتصوير تصميم المنشئ الخاص به عندما تحتاج إلى إنشاء مثيل للفئة Person. سيستغرق منشئه عشر وسائط أو أكثر، وسيكون من الصعب إدارة هذه الوسائط العديدة كوظيفة أو مُنشئ واحد، وفي النهاية، ستفقد إمكانية قراءة التعليمات البرمجية. الخروج من المثال أدناه. فكر في هذه الفئة، على سبيل المثال شخص لديه عشر خصائص أو أكثر، عندما تحتاج إلى إنشاء مثيل لفئة الشخص، تخيل تصميم المنشئ الخاص بها. يتطلب منشئه 10 معلمات أو أكثر، والتي يصعب إدارتها كوظيفة أو منشئ، وفي النهاية، تفقد إمكانية قراءة التعليمات البرمجية الخاصة بك. تحقق من المثال أدناه.


WithoutDesignPatternExample1.swift:

class Person {
  //personal details
  var name: String = ""
  var gender: String = ""
  var birthDate: String = ""
  var birthPlace: String = ""
  var height: String = ""
  var weight: String = ""
  
  //contact details
  var phone: String = ""
  var email: String = ""
  
  //address details
  var streeAddress: String = ""
  var zipCode: String = ""
  var city: String = ""
  
  //work details
  var companyName: String = ""
  var designation: String = ""
  var annualIncome: String = ""
  
  //constructor
  init(name: String,
       gender: String,
       birthDate: String,
       birthPlace: String,
       height: String,
       weight: String,
       phone: String,
       email: String,
       streeAddress: String,
       zipCode: String,
       city: String,
       companyName: String,
       designation: String,
       annualIncome: String) {
    self.name = name
    self.gender = gender
    self.birthDate = birthDate
    self.birthPlace = birthPlace
    self.height = height
    self.weight = weight
    self.phone = phone
    self.email = email
    self.streeAddress = streeAddress
    self.zipCode = zipCode
    self.height = height
    self.city = city
    self.companyName = companyName
    self.designation = designation
    self.annualIncome = annualIncome
  }
}

//This is function in Xcode-Playground which executes our test code
func main() {
  let hitendra = Person(name: "Hitendra Solanki",
                        gender: "Male",
                        birthDate: "2nd Oct 1991",
                        birthPlace: "Gujarat, India",
                        height: "5.9 ft",
                        weight: "85kg",
                        phone: "+91 90333-71772",
                        email: "hitendra.developer@gmail.com",
                        streeAddress: "52nd Godrej Street",
                        zipCode: "380015",
                        city: "Ahmedabad",
                        companyName: "Fortune 500",
                        designation: "Software architect",
                        annualIncome: "45,000 USD")
  
  //use of Person object
  print("\(hitendra.name) works in \(hitendra.companyName) compay as a \(hitendra.designation).")
}

//call main to execute our test code in Xcode-Playground
main()

/* Console output:
Hitendra Solanki works in Fortune 500 compay as a Software architect.
*/

حاول تشغيل المثال أعلاه في ساحة اللعب، وسيتم تشغيله بنجاح وسيعطيك النتيجة المتوقعة. منطقيا هو الصحيح. حاول تشغيل المثال أعلاه في ساحة اللعب، وسيتم تشغيله بنجاح وسيعطيك النتيجة المتوقعة. صحيح منطقيا.

يمكننا تحسين المثال أعلاه، من خلال التغلب على النقاط أدناه. يمكننا تحسين المثال أعلاه من خلال التغلب على النقاط التالية.

  1. علينا تمرير القيم بالترتيب المذكور، ولا يمكن إعادة ترتيب تسلسل المعلمات لتحسين إمكانية القراءة. يجب علينا تمرير القيم بالترتيب أعلاه، ولا يمكن إعادة ترتيب تسلسل المعلمات لتحسين إمكانية القراءة.

  2. علينا تمرير جميع القيم، حتى لو لم نكن نعرف بعض القيم في وقت إنشاء الكائن. يجب علينا تمرير جميع القيم، حتى لو لم نكن نعرف بعض القيم عند إنشاء الكائن.

على سبيل المثال لنفترض أنك طلبت إنشاء كائن من فئة الشخص، ولكن الشخص لا يزال يبحث عن وظيفة. عندما ينضم هذا الشخص إلى أي شركة، عندها فقط سيكون لدينا تفاصيل العمل. لنفترض أنك بحاجة إلى إنشاء كائن من فئة الشخص، ولكن الكائن لا يزال يبحث عن عمل. عندما ينضم هذا الشخص إلى أي شركة، عندها فقط سنحصل على تفاصيل الوظيفة.

الحل:

الحل:

  1. إنشاء مجموعات منطقية من الخصائص ذات الصلة. إنشاء مجموعات منطقية من الخصائص ذات الصلة.

  2. قم بإنشاء فئات إنشاء منفصلة لمجموعات مختلفة من الخصائص [يساعد في تطبيع الخصائص، وهذا اختياري. إنشاء فئات منشئة منفصلة لمجموعات سمات مختلفة [يساعد في تسوية السمات، وهذا أمر اختياري.

  3. قم باسترداد مثيل في الخطوة الأخيرة. يتم استرداد المثيل في الخطوة الأخيرة.

دعونا نبسط ذلك بمثال، دعونا نبسط الأمر بمثال

لدينا بالفعل فئة تسمى “Person” في المثال، WithDesignPatternExample1.swift، والتي لدينا فيها 14 خاصية. إذا قمنا بفحص جميع الخصائص الـ 14 عن كثب، فسنجد أن الخصائص تحتوي على 4 مجموعات منطقية. على سبيل المثال، لدينا بالفعل فئة تسمى Person بدون designpatternexample1. سويفت، لدينا 14 عقارًا. إذا قمنا بفحص جميع الخصائص الـ 14 بعناية، فسنجد أن هناك 4 مجموعات منطقية من هذه الخصائص.

  1. خصائص التفاصيل الشخصية سمات المعلومات الشخصية

  2. خصائص تفاصيل الاتصال خصائص معلومات الاتصال

  3. خصائص تفاصيل العنوان خصائص تفاصيل العنوان

  4. خصائص الشركة التفاصيل خصائص تفاصيل الشركة

يساعدنا نمط التصميم متعدد الأوجه والطلاقة معًا في التغلب على المشكلتين المذكورتين أعلاه. تساعدنا أنماط التصميم ذات الأوجه والطلاقة معًا في التغلب على المشكلتين المذكورتين أعلاه.


BuilderDesignPattern[Faceted+Fluent]Example1.swift:

//This is function in playground which executes our test code
func main() {
  
  var hitendra = Person() //person with empty details
  let personBuilder = PersonBuilder(person: hitendra)
  
  hitendra = personBuilder
    .personalInfo
      .nameIs("Hitendra Solanki")
      .genderIs("Male")
      .bornOn("2nd Oct 1991")
      .bornAt("Gujarat, India")
      .havingHeight("5.9 ft")
      .havingWeight("85 kg")
    .contacts
      .hasPhone("+91 90333-71772")
      .hasEmail("hitendra.developer@gmail.com")
    .lives
      .at("52nd Godrej Street")
      .inCity("Ahmedabad")
      .withZipCode("380015")
    .build()
  
  //use of Person object
  print("\(hitendra.name) has contact number \(hitendra.phone) and email \(hitendra.email)")
  
  //later on when we have company details ready for the person
  hitendra = personBuilder
    .works
      .asA("Software architect")
      .inCompany("Fortune 500")
      .hasAnnualEarning("45,000 USD")
    .build()
  
  //use of Person object with update info
  print("\(hitendra.name) works in \(hitendra.companyName) compay as a \(hitendra.designation).")
}

//call main to execute our test code
main()

//Person class which only contains the details
class Person {
  //personal details
  var name: String = ""
  var gender: String = ""
  var birthDate: String = ""
  var birthPlace: String = ""
  var height: String = ""
  var weight: String = ""
  
  //contact details
  var phone: String = ""
  var email: String = ""
  
  //address details
  var streeAddress: String = ""
  var zipCode: String = ""
  var city: String = ""
  
  //work details
  var companyName: String = ""
  var designation: String = ""
  var annualIncome: String = ""
  
  //empty constructor
  init() { }
}

//PersonBuilder class helps to construct the person class instance
class PersonBuilder {
  var person: Person
  init(person: Person){
    self.person = person
  }
  
  //personal details builder switching
  var personalInfo: PersonPersonalDetailsBuilder {
    return PersonPersonalDetailsBuilder(person: self.person)
  }
  
  //contact details builder switching
  var contacts: PersonContactDetailsBuilder {
    return PersonContactDetailsBuilder(person: self.person)
  }
  
  //address details builder switching
  var lives: PersonAddressDetailsBuilder {
    return PersonAddressDetailsBuilder(person: self.person)
  }
  
  //work details builder switching
  var works: PersonCompanyDetailsBuilder {
    return PersonCompanyDetailsBuilder(person: self.person)
  }
  
  func build() -> Person {
    return self.person
  }
}

//PersonPersonalDetailsBuilder: update personal details
class PersonPersonalDetailsBuilder: PersonBuilder {
  func nameIs(_ name: String) -> Self {
    self.person.name = name
    return self
  }
  func genderIs(_ gender: String) -> Self {
    self.person.gender = gender
    return self
  }
  func bornOn(_ birthDate: String) -> Self {
    self.person.birthDate = birthDate
    return self
  }
  func bornAt(_ birthPlace: String) -> Self {
    self.person.birthPlace = birthPlace
    return self
  }
  func havingHeight(_ height: String) -> Self {
    self.person.height = height
    return self
  }
  func havingWeight(_ weight: String) -> Self {
    self.person.weight = weight
    return self
  }
}

//PersonContactDetailsBuilder: update contact details
class PersonContactDetailsBuilder: PersonBuilder {
  func hasPhone(_ phone: String) -> Self {
    self.person.phone = phone
    return self
  }
  func hasEmail(_ email: String) -> Self {
    self.person.email = email
    return self
  }
}

//PersonAddressDetailsBuilder: update address details
class PersonAddressDetailsBuilder: PersonBuilder {
  func at(_ streeAddress: String) -> Self {
    self.person.streeAddress = streeAddress
    return self
  }
  func withZipCode(_ zipCode: String) -> Self {
    self.person.zipCode = zipCode
    return self
  }
  func inCity(_ city: String) -> Self {
    self.person.city = city
    return self
  }
}

//PersonCompanyDetailsBuilder: update company details
class PersonCompanyDetailsBuilder: PersonBuilder {
  func inCompany(_ companyName: String) -> Self {
    self.person.companyName = companyName
    return self
  }
  func asA(_ designation: String) -> Self {
    self.person.designation = designation
    return self
  }
  func hasAnnualEarning(_ annualIncome: String) -> Self {
    self.person.annualIncome = annualIncome
    return self
  }
}

/* Console output:
 
 Hitendra Solanki has contact number +91 90333-71772 and email hitendra.developer@gmail.com
 Hitendra Solanki works in Fortune 500 compay as a Software architect.
 
 */

في المثال أعلاه، قمنا بفصل مسؤوليات فئة الشخص في فئات مختلفة. تحتفظ فئة الشخص الآن بخصائص البيانات فقط، بينما أنشأنا فئات منشئة متعددة لها مسؤوليات لبناء/تحديث المجموعة النسبية للخصائص. في المثال أعلاه، قمنا بتقسيم مسؤوليات فئة الشخص إلى فئات مختلفة. تحتوي فئة الشخص الآن على سمات البيانات فقط، وقد أنشأنا فئات منشئة متعددة مسؤولة عن إنشاء/تحديث مجموعات السمات ذات الصلة.لدينا فئة منشئ أساسية واحدة PersonBuilder ولدينا أربع فئات منشئ مشتقة أخرى تسمى PersonPersonalDetailsBuilder وPersonContactDetailsBuilder وPersonAddressDetailsBuilder وPersonCompanyDetailsBuilder. لدينا فئة منشئ أساسية PersonBuilder، وأربع فئات منشئ مشتقة، وهي PersonPersonalDetailsBuilder، وPersonContactDetailsBuilder، وPersonAddressDetailsBuilder، وPersonCompanyDetailsBuilder.

تساعدنا الفئة الأساسية PersonBuilder على التبديل بين منشئين متعددين في أي وقت بينما يتحمل المنشئون الأربعة الآخرون المشتقون من PersonBuilder مسؤوليات لتحديث الخصائص النسبية. تساعدنا الفئة الأساسية PersonBuilder على التبديل بين العديد من أدوات الإنشاء في أي وقت، بينما تكون أدوات الإنشاء الأربعة الأخرى المشتقة من PersonBuilder مسؤولة عن تحديث الخصائص ذات الصلة.

في المثال أعلاه، يمكننا أن نرى بوضوح أن بناء كائن Person أكثر قابلية للقراءة مقارنة بمثالنا الأول، WithDesignPatternExample1.swift، كما يمكننا تحديث مجموعة الخصائص أو أي خاصية مفردة في أي وقت بطريقة أكثر قابلية للقراءة. في المثال أعلاه، يمكننا أن نرى بوضوح أن بنية كائن الشخص أكثر قابلية للقراءة مقارنة بمثالنا الأول.

في المثال أعلاه، لاحظ أننا نعيد نسخة المنشئ ذاتيًا بعد استدعاء كل طريقة لتحديث الخاصية. مما يساعدنا على كتابة تسلسل طرق متعددة لنفس المنشئ بدلاً من كتابة أسطر متعددة بشكل منفصل. يُعرف هذا المفهوم باسم النمط بطلاقة. في المثال أعلاه، لاحظ أنه بعد استدعاء كل طريقة لتحديث الخاصية، فإننا نعيد نسخة المولد نفسها. يساعدنا هذا في كتابة تسلسل لطرق متعددة لنفس المولد بدلاً من كتابة عدة أسطر منفصلة. ويسمى هذا المفهوم وضع التماسك.

الفوائد:

الفوائد:

  1. من السهل تهيئة كائن من فئة يحتوي على الكثير من الخصائص بطريقة أكثر قابلية للقراءة. يقوم بسهولة بتهيئة كائن من فئة يحتوي على عدد كبير جدًا من الخصائص، من أجل سهولة القراءة.

  2. يتبع مبدأ المسؤولية الفردية. اتبع مبدأ المسؤولية الفردية.

  3. قم بتهيئة الكائن أو تحديث الخصائص بأي ترتيب يناسبك. تهيئة الكائنات أو تحديث الخصائص بأي ترتيب يناسبك.

###مكافأة: المكافأة:

لجعل نمط المنشئ متسقًا عبر المشروع بأكمله، يمكنك إنشاء بروتوكول على النحو التالي. لجعل نمط المولد متسقًا خلال مشروعك، يمكنك إنشاء بروتوكول مثل ما يلي.

النص الأصلي: https://medium.com/flawless-app-stories/design-patterns-by-tutorials-the-power-of-oop-2e871b551cbe