سؤال

لقد بدأت للتو في تعلم أنماط التصميم ولدي سؤالان يتعلقان بالديكور ...

كنت أتساءل لماذا يشير نمط الديكور إلى أن الديكور ينفذ جميع الأساليب العامة للمكون الذي يزينه؟

لا يمكن استخدام فئة الديكور فقط لتوفير السلوكيات الإضافية ، ثم يتم استخدام المكون الخرساني (الذي يتم تمريره إليه) فقط لاستدعاء كل شيء آخر؟

وثانياً ، ماذا لو أن المكون الخرساني الذي تريد تزيينه لا يحتوي على فئة أساسية يمكن أن يستمدها الديكور التجريدي أيضًا؟

شكرا مقدما!

هل كانت مفيدة؟

المحلول

أعتقد أنك قد أسيء فهم الديكور. أنت تفكر في حالة بسيطة لتوسيع فئة ملموسة ذات وظائف إضافية. في هذه الحالة ، نعم في معظم لغات OO ، يمكن للطبقة المشتقة ببساطة السماح لطبقة الفئة الفائقة بالتعامل مع أي طرق غير محدودة.

class Base {

  function foo() {
    return "foo";
  }

  function bar() {
    return "bar";
  }

}

// Not what we think of as a Decorator,
// really just a subclass.
class Decorator extends Base {

  // foo() inherits behavior from parent Base class 

  function bar() {
    return parent::bar() . "!"; // add something
  }

}

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

class Decorator { // extends nothing
  protected $base;

  function __construct(Base $base) {
    $this->base = $base;
  }

  function foo() {
    return $base->foo();
  }

  function bar() {
    return $base->foo() . "!"; // add something
  }

}

قد يكون من المفيد تحديد واجهه المستخدم (إذا كانت لغتك تدعم مثل هذا الشيء) لكل من الفئة المزينة وفئة الديكور. وبهذه الطريقة ، يمكنك التحقق من وقت الترجمة الذي يقوم به الديكور نفس الواجهة.

interface IBase {
  function foo();
  function bar();
}

class Base implements IBase {
  . . .
}

class Decorator implements IBase {
  . . .
}

رد: تعليق Yossi Dahan: أرى الغموض في مقالة ويكيبيديا ، ولكن إذا قرأت بعناية ، فإن العنصر الذي يتم تزيينه هو أ مجال في كائن الديكور ، ويتم تمرير المكون كحجة إلى مُنشئ الديكور. هذا يختلف عن الميراث.

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

فيما يلي بعض المقتطفات من "أنماط التصميم: عناصر من البرامج الموجه نحو الكائنات القابلة لإعادة الاستخدام" من تأليف جاما ، هيلم ، جونسون ، وفليسيد:

ديكور

نية

نعلق مسؤوليات إضافية إلى كائن ديناميكي. يوفر الديكورات بديلاً مرنًا للتصنيف الفرعي لتوسيع الوظائف.

تحفيز

... يتوافق الديكور مع واجهة المكون الذي يزينه بحيث يكون وجوده شفافًا لعملاء المكون.

مشاركون

  • يحتفظ ديكور مرجع إلى كائن مكون ويحدد واجهة تتوافق مع واجهة المكون.

نصائح أخرى

كنت أتساءل لماذا يشير نمط الديكور إلى أن الديكور ينفذ جميع الأساليب العامة للمكون الذي يزينه؟

يجب أن يكون الديكور انخفاضًا في الاستبدال للمكون الذي يزينه ، مع وظائف إضافية ("الديكور"). لا يمكن أن يحدث هذا إلا إذا قام بتنفيذ واجهة المكون بالكامل.

لا يمكن استخدام فئة الديكور فقط لتوفير السلوكيات الإضافية ، ثم يتم استخدام المكون الخرساني (الذي يتم تمريره إليه) فقط لاستدعاء كل شيء آخر؟

وهذا يجعل الافتراضات حول كيفية تنفيذ الديكور. لا يمكنك التأكد من أن الواجهة العامة بأكملها للمكون الذي تزينه يتم تمريره مباشرة. من الممكن أن يتجاوز الديكور طرقًا معينة في تنفيذه.

وثانياً ، ماذا لو أن المكون الخرساني الذي تريد تزيينه لا يحتوي على فئة أساسية يمكن أن يستمدها الديكور التجريدي أيضًا؟

يرث الديكور عمومًا فئة المكون التي يزينها ، وليس قاعدة المكون.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top