Builder Pattern

Builder Pattern هو نمط تصميم إبداعي يستخدم لبناء كائنات معقدة خطوة بخطوة. بدلاً من إنشاء كائن باستخدام constructor طويل أو العديد من المعلمات الاختيارية، يفصل Builder Pattern عملية الإنشاء عن الكائن النهائي.

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

مقدمة

في المقالات السابقة من سلسلة Design Patterns، ناقشنا Factory Pattern وAbstract Factory Pattern. يركز كلا النموذجين على إنشاء الكائنات، لكنهما يحلان مشكلات مختلفة.

يكون Factory Pattern مفيدًا عندما يحتاج التطبيق إلى تحديد نوع الكائن الذي سيتم إنشاؤه. يكون Abstract Factory Pattern مفيدًا عندما يحتاج التطبيق إلى إنشاء عائلات من الكائنات ذات الصلة. يختلف Builder Pattern لأنه يركز على كيفية إنشاء كائن معقد خطوة بخطوة.

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

ما هو Builder Pattern؟

Builder Pattern هو نمط تصميم إبداعي يسمح للمطورين ببناء كائنات معقدة تدريجيًا. فهو يوفر builder class طرقًا لتعيين أجزاء مختلفة من الكائن، ثم يقوم بإرجاع الكائن النهائي عند اكتمال البناء.

بعبارات بسيطة، بدلاً من إنشاء كائن في خطوة واحدة كبيرة، يقوم Builder Pattern بإنشائه من خلال عدة خطوات أصغر.

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

لماذا يعد Builder Pattern مهمًا

يعد Builder Pattern مهمًا لأن constructors قد يصبح من الصعب إدارته عندما تحتوي الكائنات على العديد من المعلمات. تسمى هذه المشكلة غالبًا بمشكلة التلسكوب constructor.

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

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

مشكلة Constructors الكبيرة

تخيل class الذي يمثل ملف تعريف المستخدم. وقد تتضمن الاسم والبريد الإلكتروني والهاتف والعنوان والصورة الرمزية والسيرة الذاتية والروابط الاجتماعية وإعدادات الإشعارات وإعدادات الخصوصية وتفضيلات اللغة.

بدون Builder Pattern، قد يبدو constructor كما يلي:

$profile = new UserProfile(
    'Adnan Mehrat',
    'adnan@example.com',
    '+905000000000',
    'Samsun',
    'Turkey',
    'Developer',
    true,
    false,
    'en'
);

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

Builder Pattern يحل هذه المشكلة عن طريق جعل عملية البناء أكثر قابلية للقراءة.

Builder Pattern مثال أساسي في PHP

يوضح المثال التالي تطبيق Builder Pattern البسيط لإنشاء ملف تعريف المستخدم:

class UserProfile
{
    public function __construct(
        public string $name,
        public string $email,
        public ?string $phone = null,
        public ?string $city = null,
        public ?string $country = null,
        public ?string $bio = null,
        public bool $isPublic = true
    ) {
    }
}

class UserProfileBuilder
{
    private string $name;
    private string $email;
    private ?string $phone = null;
    private ?string $city = null;
    private ?string $country = null;
    private ?string $bio = null;
    private bool $isPublic = true;

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function setEmail(string $email): self
    {
        $this->email = $email;

        return $this;
    }

    public function setPhone(string $phone): self
    {
        $this->phone = $phone;

        return $this;
    }

    public function setLocation(string $city, string $country): self
    {
        $this->city = $city;
        $this->country = $country;

        return $this;
    }

    public function setBio(string $bio): self
    {
        $this->bio = $bio;

        return $this;
    }

    public function makePrivate(): self
    {
        $this->isPublic = false;

        return $this;
    }

    public function build(): UserProfile
    {
        return new UserProfile(
            $this->name,
            $this->email,
            $this->phone,
            $this->city,
            $this->country,
            $this->bio,
            $this->isPublic
        );
    }
}

في هذا المثال، يقوم builder بتخزين قيم البناء وإرجاع كائن UserProfile النهائي من خلال أسلوب الإنشاء.

باستخدام Builder Pattern

بعد إنشاء builder، يصبح بناء الكائن أكثر قابلية للقراءة:

$profile = (new UserProfileBuilder())
    ->setName('Adnan Mehrat')
    ->setEmail('adnan@example.com')
    ->setPhone('+905000000000')
    ->setLocation('Samsun', 'Turkey')
    ->setBio('Backend-focused full stack developer')
    ->makePrivate()
    ->build();

من السهل فهم هذا الرمز لأن كل اسم طريقة يشرح القيمة التي يتم تعيينها. خطوات البناء واضحة ومنظمة.

يُطلق على هذا النمط غالبًا اسم interface بطلاقة لأن كل أسلوب يُرجع builder نفسه ويسمح بتسلسل الأساليب.

الأجزاء الرئيسية من Builder Pattern

يتضمن Builder Pattern عادةً الأجزاء التالية:

  • المنتج: الكائن النهائي الذي يتم إنشاؤه.
  • Builder: class المسؤول عن ضبط أجزاء الكائن خطوة بخطوة.
  • طريقة البناء: الطريقة التي تُرجع الكائن النهائي.
  • المخرج: class اختياري يتحكم في عملية البناء المحددة مسبقًا.

ليس كل تنفيذ يحتاج إلى مدير. في العديد من تطبيقات PHP، يكفي استخدام builder class البسيط.

Builder Pattern مع المخرج

المخرج هو class الذي يحدد تسلسلات البناء الشائعة. ويستخدم builder لإنشاء الكائنات بطريقة قياسية.

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

class Report
{
    public function __construct(
        public string $title,
        public string $period,
        public array $sections,
        public bool $includeCharts
    ) {
    }
}

class ReportBuilder
{
    private string $title = '';
    private string $period = '';
    private array $sections = [];
    private bool $includeCharts = false;

    public function setTitle(string $title): self
    {
        $this->title = $title;

        return $this;
    }

    public function setPeriod(string $period): self
    {
        $this->period = $period;

        return $this;
    }

    public function addSection(string $section): self
    {
        $this->sections[] = $section;

        return $this;
    }

    public function includeCharts(): self
    {
        $this->includeCharts = true;

        return $this;
    }

    public function build(): Report
    {
        return new Report(
            $this->title,
            $this->period,
            $this->sections,
            $this->includeCharts
        );
    }
}

class ReportDirector
{
    public function createMonthlyReport(ReportBuilder $builder): Report
    {
        return $builder
            ->setTitle('Monthly Sales Report')
            ->setPeriod('Monthly')
            ->addSection('Summary')
            ->addSection('Sales')
            ->addSection('Expenses')
            ->includeCharts()
            ->build();
    }
}

في هذا المثال، يحدد ReportDirector طريقة قياسية لإنشاء تقرير شهري. يمكن أن يكون هذا مفيدًا عند تكرار عملية البناء نفسها في أماكن متعددة.

عندما يكون المدير مفيدا

يكون المدير مفيدًا عندما يكون لدى التطبيق سير عمل إنشاء كائن محدد مسبقًا. بدلاً من تكرار نفس خطوات builder في العديد من الأماكن، يقوم المدير بمركزية العملية.

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

ومع ذلك، إذا كان إنشاء الكائن بسيطًا أو تم إنشاء كل كائن بشكل مختلف، فقد يكون استخدام المخرج غير ضروري.

مثال من العالم الحقيقي: رسالة البريد الإلكتروني Builder

تعد رسالة البريد الإلكتروني مثالًا عمليًا على Builder Pattern. يمكن أن تحتوي رسائل البريد الإلكتروني على العديد من الأجزاء الاختيارية مثل CC وBCC والمرفقات والأولوية والقالب والبيانات التعريفية.

class EmailMessage
{
    public function __construct(
        public string $to,
        public string $subject,
        public string $body,
        public array $cc = [],
        public array $bcc = [],
        public array $attachments = [],
        public string $priority = 'normal'
    ) {
    }
}

class EmailMessageBuilder
{
    private string $to;
    private string $subject;
    private string $body;
    private array $cc = [];
    private array $bcc = [];
    private array $attachments = [];
    private string $priority = 'normal';

    public function to(string $email): self
    {
        $this->to = $email;

        return $this;
    }

    public function subject(string $subject): self
    {
        $this->subject = $subject;

        return $this;
    }

    public function body(string $body): self
    {
        $this->body = $body;

        return $this;
    }

    public function cc(string $email): self
    {
        $this->cc[] = $email;

        return $this;
    }

    public function bcc(string $email): self
    {
        $this->bcc[] = $email;

        return $this;
    }

    public function attach(string $filePath): self
    {
        $this->attachments[] = $filePath;

        return $this;
    }

    public function highPriority(): self
    {
        $this->priority = 'high';

        return $this;
    }

    public function build(): EmailMessage
    {
        return new EmailMessage(
            $this->to,
            $this->subject,
            $this->body,
            $this->cc,
            $this->bcc,
            $this->attachments,
            $this->priority
        );
    }
}

يجعل builder عملية إنشاء البريد الإلكتروني واضحة ومرنة.

باستخدام البريد الإلكتروني Builder

$email = (new EmailMessageBuilder())
    ->to('user@example.com')
    ->subject('Welcome to our platform')
    ->body('Thank you for joining us.')
    ->cc('manager@example.com')
    ->attach('/files/welcome.pdf')
    ->highPriority()
    ->build();

يعد هذا الأسلوب أكثر قابلية للقراءة من تمرير العديد من المصفوفات والمعلمات الاختيارية في constructor واحد.

Builder Pattern والكائنات غير القابلة للتغيير

يعمل Builder Pattern بشكل جيد مع الكائنات غير القابلة للتغيير. الكائن غير القابل للتغيير هو كائن لا يمكن تغيير حالته بعد إنشائه.

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

على سبيل المثال، يمكن أن تستفيد كائنات التكوين وكائنات القيمة وكائنات request وDTOs من هذا الأسلوب. يقوم builder بجمع القيم والتحقق من صحتها ثم يقوم بإنشاء كائن نهائي مستقر.

التحقق من الصحة داخل Builder

يمكن لـ builder أيضًا التحقق من صحة القيم المطلوبة قبل إنشاء الكائن النهائي. تم إنشاء كائنات prevent غير الكاملة أو غير الصالحة.

public function build(): EmailMessage
{
    if (empty($this->to)) {
        throw new InvalidArgumentException('Recipient email is required.');
    }

    if (empty($this->subject)) {
        throw new InvalidArgumentException('Email subject is required.');
    }

    if (empty($this->body)) {
        throw new InvalidArgumentException('Email body is required.');
    }

    return new EmailMessage(
        $this->to,
        $this->subject,
        $this->body,
        $this->cc,
        $this->bcc,
        $this->attachments,
        $this->priority
    );
}

وهذا يضمن أن الكائن كامل وصالح قبل استخدامه بواسطة التطبيق.

Builder Pattern مقابل Factory Pattern

يعد كل من Builder Pattern وFactory Pattern من الأنماط الإبداعية، لكنهما يحلان مشكلات مختلفة.

يركز Factory Pattern على اختيار الكائن المراد إنشاؤه. على سبيل المثال، قد يقرر PaymentFactory ما إذا كان سيتم إنشاء CreditCardPayment أو PayPalPayment.

يركز Builder Pattern على كيفية إنشاء كائن معقد خطوة بخطوة. على سبيل المثال، قد يقوم EmailMessageBuilder بتعيين المستلم، subject، والنص، وCC، وBCC، والمرفقات، والأولوية قبل إنشاء EmailMessage النهائي.

باختصار، يجيب Factory على "ما هو الكائن الذي يجب إنشاؤه؟" بينما يجيب Builder على "كيف ينبغي بناء هذا الكائن المعقد؟"

Builder Pattern مقابل Abstract Factory Pattern

يقوم Abstract Factory Pattern بإنشاء عائلات من الكائنات ذات الصلة. يقوم Builder Pattern بإنشاء كائن واحد معقد من خلال خطوات متعددة.

على سبيل المثال، قد يقوم Abstract Factory بإنشاء مجموعة من مكونات واجهة المستخدم مثل Button وInput وModal لموضوع داكن. قد يقوم Builder بإنشاء كائن صفحة معقد واحد يحتوي على العنوان والتخطيط والأقسام وبيانات التعريف والإعدادات.

يدعم كلا النمطين إنشاء كائنات أفضل، لكن الغرض منهما مختلف.

Builder Pattern في Laravel

يستخدم مطورو Laravel نمط builder APIs بشكل متكرر. على سبيل المثال، يسمح استعلام Laravel builder للمطورين ببناء استعلامات قاعدة البيانات خطوة بخطوة باستخدام تسلسل الأساليب.

$users = DB::table('users')
    ->where('active', true)
    ->orderBy('created_at', 'desc')
    ->limit(10)
    ->get();

يشبه هذا النمط Builder Pattern لأنه يتم إنشاء الاستعلام تدريجيًا قبل التنفيذ.

يمكن للمطورين أيضًا إنشاء builders مخصصة للتقارير أو عوامل التصفية أو استعلامات البحث أو تكوين التصدير أو API requests أو كائنات DTO المعقدة في تطبيقات Laravel.

Builder Pattern في Symfony

يمكن لتطبيقات Symfony أيضًا استخدام builder classes لإنشاء كائنات معقدة. على سبيل المثال، يمكن أن تساعد builders في تكوين تكوينات النموذج، أو حمولات request، أو كائنات الرسائل، أو عمليات تصدير التقارير.

عند دمجه مع dependency injection، يمكن أن يظل builder classes نظيفًا وقابلاً لإعادة الاستخدام. ويمكن أيضًا اختبارها بشكل منفصل عن وحدات التحكم والخدمات.

حالات الاستخدام الحقيقي لـ Builder Pattern

يعد Builder Pattern مفيدًا في العديد من سيناريوهات تطوير البرامج الحقيقية.

تشمل حالات الاستخدام الشائعة ما يلي:

  • إنشاء رسائل بريد إلكتروني باستخدام CC وBCC والمرفقات الاختيارية.
  • إنشاء تقارير بالأقسام والمخططات والمرشحات وخيارات التصدير.
  • إنشاء HTTP requests باستخدام الرؤوس ومعلمات الاستعلام وبيانات النص.
  • إنشاء DTOs معقدة أو كائنات القيمة.
  • بناء عوامل تصفية البحث أو كائنات الاستعلام.
  • إنشاء كائنات الفاتورة بالأصناف والضرائب والخصومات والبيانات الوصفية.
  • بناء كائنات التكوين مع العديد من الإعدادات الاختيارية.

في كل هذه الحالات، يعمل Builder Pattern على تحسين إمكانية القراءة ويحافظ على تنظيم عملية إنشاء الكائنات.

فوائد Builder Pattern

يوفر Builder Pattern العديد من الفوائد عندما يكون للكائن العديد من خطوات البناء الاختيارية أو المعقدة.

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

  • يحسن إمكانية قراءة رمز إنشاء الكائن.
  • يتجنب constructors الطويل مع العديد من المعلمات.
  • يدعم بناء الكائن خطوة بخطوة.
  • يجعل القيم الاختيارية أسهل في الإدارة.
  • يمكن التحقق من صحة القيم المطلوبة قبل إنشاء الكائن.
  • يعمل بشكل جيد مع الكائنات غير القابلة للتغيير.
  • يدعم interfaces وتسلسل الطريقة بطلاقة.
  • يفصل منطق البناء عن الكائن النهائي.

هذه الفوائد تجعل Builder Pattern عمليًا جدًا لإنشاء الكائنات المعقدة.

عيوب Builder Pattern

على الرغم من أن Builder Pattern مفيد، إلا أن له عيوبًا أيضًا. يمكنه إضافة classes إضافي والمزيد من الكود. بالنسبة للكائنات البسيطة، قد تكون هذه البنية الإضافية غير ضرورية.

إذا كان الكائن يحتوي على معلمتين أو ثلاث معلمات مطلوبة فقط، فقد يكون constructor العادي أكثر وضوحًا من builder. يمكن أن تؤدي إضافة builder لكل class إلى جعل المشروع أكثر تعقيدًا.

عيب آخر هو أن builder ذو التصميم السيئ يمكن أن يسمح بحالات وسيطة غير صالحة. ولهذا السبب يعد التحقق من الصحة في طريقة الإنشاء أمرًا مهمًا عند وجود القيم المطلوبة.

متى يتم استخدام Builder Pattern

استخدم Builder Pattern عندما يكون إنشاء الكائن معقدًا أو اختياريًا أو يصعب قراءته باستخدام constructor العادي.

يكون Builder Pattern مفيدًا عندما:

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

في حالة وجود هذه الشروط، يمكن لـ Builder Pattern تحسين جودة الكود بشكل ملحوظ.

متى لا تستخدم Builder Pattern

لا تستخدم Builder Pattern عندما يكون إنشاء الكائن أمرًا بسيطًا. إذا كان class يحتوي فقط على عدد قليل من القيم المطلوبة ولا يوجد إعداد معقد، فإن constructor العادي يكون أفضل عادةً.

تجنب Builder Pattern عندما:

  • يحتوي الكائن على عدد قليل جدًا من المعلمات.
  • إن constructor واضح بالفعل وقابل للقراءة.
  • سوف يقوم builder بتكرار منطق constructor فقط.
  • المشروع لا يحتاج إلى بناء خطوة بخطوة.
  • يضيف النمط تعقيدًا أكثر من القيمة.

يجب أن يحل Design patterns المشكلات الحقيقية. ولا ينبغي إضافتها فقط لجعل الكود تبدو أكثر تقدمًا.

Builder Pattern والكود النظيف

يدعم Builder Pattern الكود النظيفة عن طريق جعل إنشاء الكائنات أكثر تعبيرًا. بدلاً من تمرير قيم غير واضحة إلى constructor طويلة، تشرح كل طريقة builder الغرض من القيمة.

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

ومع ذلك، فإن الكود النظيف يعني أيضًا تجنب التعقيد غير الضروري. يجب استخدام Builders فقط عندما تجعل البناء أكثر وضوحًا.

الأخطاء الشائعة في Builder Pattern

أحد الأخطاء الشائعة هو استخدام Builder Pattern لكل كائن، حتى عندما يكون constructors بسيطًا. يؤدي هذا إلى إنشاء عدد كبير جدًا من ملفات classes غير الضرورية.

خطأ آخر هو عدم التحقق من صحة القيم المطلوبة قبل بناء الكائن. يمكن أن يسمح هذا بإنشاء كائنات غير مكتملة.

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

الخطأ الرابع هو جعل أساليب builder غير واضحة أو غير متناسقة. يجب أن تصف أسماء الطرق خطوة البناء بوضوح.

أفضل الممارسات لـ Builder Pattern

لاستخدام Builder Pattern بشكل فعال، يجب على المطورين إبقاء builder يركز على البناء وجعل API قابلاً للقراءة.

تتضمن أفضل الممارسات المفيدة ما يلي:

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

تساعد هذه الممارسات المطورين على تطبيق Builder Pattern بطريقة عملية وقابلة للصيانة.

قائمة مرجعية عملية قبل استخدام Builder Pattern

قبل استخدام Builder Pattern، يمكن للمطورين طرح هذه الأسئلة:

  • هل يحتوي الكائن على العديد من المعلمات؟
  • هل العديد من المعلمات اختيارية؟
  • هل من الصعب قراءة constructor؟
  • هل يمكن الخلط بين القيم لأن لها أنواعًا متشابهة؟
  • هل يحتاج الكائن إلى البناء خطوة بخطوة؟
  • هل يجب أن يكون الكائن النهائي غير قابل للتغيير؟
  • هل سيجعل builder الكود أكثر وضوحًا؟

إذا كانت الإجابة بنعم على العديد من هذه الأسئلة، فقد يكون Builder Pattern خيارًا جيدًا.

الاستنتاج

Builder Pattern هو نمط تصميم إبداعي يستخدم لبناء كائنات معقدة خطوة بخطوة. يكون مفيدًا بشكل خاص عندما يحتوي الكائن على العديد من المعلمات الاختيارية أو القيم المتداخلة أو خيارات التكوين أو قواعد التحقق من الصحة.

يعمل Builder Pattern على تحسين إمكانية القراءة عن طريق استبدال constructors الطويل باستدعاءات الطريقة الواضحة. فهو يفصل منطق البناء عن الكائن النهائي ويعمل بشكل جيد مع الكائنات غير القابلة للتغيير، وDTOs، والتقارير، ورسائل البريد الإلكتروني، وHTTP requests، وكائنات التكوين.

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