Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

نمط Abstract Factory

جزء من قسم البرمجة كائنية التوجه في رحلة GO على Coddy. الدرس 88 من 107.

يمدّد Abstract Factory pattern نمط Factory من خلال إنشاء عائلات من الكائنات المرتبطة دون تحديد أنواعها الملموسة. وبدلاً من factory function واحدة، تحدد واجهة factory تنفذها مصانع ملموسة متعددة، بحيث ينتج كل منها مجموعة متسقة من الكائنات المرتبطة.

تخيّل مجموعة أدوات لواجهة المستخدم تحتاج إلى إنشاء أزرار ومربعات اختيار. تتطلب أنظمة التشغيل المختلفة تطبيقات مختلفة، ولكن يجب أن تعمل المكوّنات معًا بشكل متسق:

type Button interface {
    Render() string
}

type Checkbox interface {
    Check() string
}

// واجهة المصنع التجريدي
type GUIFactory interface {
    CreateButton() Button
    CreateCheckbox() Checkbox
}

ينتج كل مصنع ملموس عائلة من المكوّنات ذات الصلة:

// عائلة Windows
type WindowsButton struct{}
func (w WindowsButton) Render() string { return "Windows Button" }

type WindowsCheckbox struct{}
func (w WindowsCheckbox) Check() string { return "Windows Checkbox" }

type WindowsFactory struct{}
func (w WindowsFactory) CreateButton() Button { return WindowsButton{} }
func (w WindowsFactory) CreateCheckbox() Checkbox { return WindowsCheckbox{} }

// عائلة Mac
type MacButton struct{}
func (m MacButton) Render() string { return "Mac Button" }

type MacCheckbox struct{}
func (m MacCheckbox) Check() string { return "Mac Checkbox" }

type MacFactory struct{}
func (m MacFactory) CreateButton() Button { return MacButton{} }
func (m MacFactory) CreateCheckbox() Checkbox { return MacCheckbox{} }

يتعامل كود العميل مع factory interface، مع بقائه مستقلًا عن التطبيقات الملموسة:

func BuildUI(factory GUIFactory) {
    button := factory.CreateButton()
    checkbox := factory.CreateCheckbox()
    fmt.Println(button.Render(), checkbox.Check())
}

استخدم Abstract Factory عندما يحتاج نظامك إلى العمل مع عدة families من المنتجات المرتبطة وتريد ضمان استخدام مكوّنات من family نفسها معًا. فهو أكثر تعقيدًا من Factory بسيط، لذا لا تلجأ إليه إلا عندما تحتاج حقًا إلى إدارة families المنتجات.

challenge icon

التحدي

سهل

لنَبْنِ نظام متجر أثاث باستخدام نمط Abstract Factory! ستنشئ مصانع تنتج عائلات من عناصر الأثاث المرتبطة: إذ ينتج كل مصنع نمطًا متناسقًا (Modern أو Vintage)، مما يضمن توافق الكراسي والطاولات من المصنع نفسه من الناحية الجمالية.

ستنظم التعليمات البرمجية عبر ثلاثة ملفات:

  • furniture.go: Define واجهات المنتجات وأنواع الأثاث الملموسة.

    أنشئ واجهتي منتج:

    • Chair مع method هي SitOn() string
    • Table مع method هي PlaceItems() string

    Implement عائلتين من furniture:

    • Modern family: يعيد ModernChair القيمة Sitting on a sleek modern chair، ويعيد ModernTable القيمة Placing items on a glass modern table
    • Vintage family: يعيد VintageChair القيمة Sitting on an ornate vintage chair، ويعيد VintageTable القيمة Placing items on a wooden vintage table
  • factory.go: Define واجهة المصنع Abstract ومصانع ملموسة.

    أنشئ واجهة FurnitureFactory مع methodين:

    • CreateChair() Chair
    • CreateTable() Table

    Implement مصنعين ملموسين:

    • ModernFactory الذي ينتج ModernChair وModernTable
    • VintageFactory الذي ينتج VintageChair وVintageTable

    أنشئ أيضًا function باسم GetFactory(style string) FurnitureFactory يعيد المصنع المناسب استنادًا إلى النمط (modern أو vintage). استخدم ModernFactory افتراضيًا للأنماط غير المعروفة.

  • main.go: استخدم مصانعك لتأثيث الغرف.

    أنشئ function باسم FurnishRoom(factory FurnitureFactory) string تستخدم المصنع لإنشاء كرسي وطاولة، ثم تعيد سلسلة نصية formatted تعرض الإجراءين في سطرين منفصلين.

    اقرأ إدخال النمط، واحصل على المصنع المناسب، وأثّث غرفة، ثم اطبع النتيجة.

سيتم توفير المدخلات التالية:

  • السطر 1: نمط الأثاث (modern أو vintage أو أي قيمة أخرى)

على سبيل المثال، عند إعطاء:

modern

يجب أن يكون الناتج:

Sitting on a sleek modern chair
Placing items on a glass modern table

وعند إعطاء:

vintage

يجب أن يكون الناتج:

Sitting on an ornate vintage chair
Placing items on a wooden vintage table

وعند إعطاء:

rustic

يجب أن يكون الناتج:

Sitting on a sleek modern chair
Placing items on a glass modern table

لاحظ كيف تعمل function FurnishRoom مع أي مصنع من خلال الواجهة. فهي لا تعرف ما إذا كانت تنشئ أثاثًا Modern أو Vintage. وهذا يضمن أن يأتي كل الأثاث في الغرفة من العائلة نفسها، مع الحفاظ على نمط متناسق!

جرّب بنفسك

package main

import "fmt"

// FurnishRoom تستخدم مصنعاً لإنشاء الأثاث وتُرجع النتيجة
// TODO: نفّذ هذه الدالة
// - استخدم المصنع لإنشاء كرسي وطاولة
// - أعد سلسلة نصية بنتيجة SitOn() في السطر الأول ونتيجة PlaceItems() في السطر الثاني
func FurnishRoom(factory FurnitureFactory) string {
	// TODO: أنشئ كرسياً وطاولة باستخدام المصنع
	// TODO: أعد سلسلة منسّقة بكلا الإجراءين في أسطر منفصلة
	return ""
}

func main() {
	var style string
	fmt.Scanln(&style)

	// TODO: احصل على المصنع المناسب بناءً على style
	// TODO: جهّز غرفة باستخدام المصنع
	// TODO: اطبع النتيجة
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

13أنماط التصميم - الجزء الأول

مقدمة في أنماط التصميمنمط Singletonنمط Factoryنمط Abstract Factoryنمط Observerنمط Strategy

تدرّب بنفسك: مترجم Go عبر الإنترنت