Files

8.1 KiB

title, shortTitle, category, language, tag
title shortTitle category language tag
Composite Composite Structural ar
Gang of Four
Object composition
Recursion

أيضًا يُعرف بـ

  • شجرة الكائنات
  • الهيكل المركب

الهدف

تركيب الكائنات في هياكل شجرية لتمثيل التسلسل الهرمي "جزء-كامل". يسمح نمط المركب للعملاء بمعاملة الكائنات الفردية وتركيبات الكائنات بطريقة موحدة.

الشرح

مثال واقعي

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

بكلمات بسيطة

يسمح نمط المركب للعملاء بمعاملة الكائنات الفردية بطريقة موحدة.

تقول ويكيبيديا

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

مثال برمجي

باستخدام مثالنا السابق، هنا لدينا الفئة الأساسية LetterComposite وأنواع مختلفة من الكائنات القابلة للطباعة مثل Letter, Word, و Sentence.

public abstract class LetterComposite {

    private final List<LetterComposite> children = new ArrayList<>();

    public void add(LetterComposite letter) {
        children.add(letter);
    }

    public int count() {
        return children.size();
    }

    protected void printThisBefore() {
    }

    protected void printThisAfter() {
    }

    public void print() {
        printThisBefore();
        children.forEach(LetterComposite::print);
        printThisAfter();
    }
}

public class Letter extends LetterComposite {

    private final char character;

    public Letter(char c) {
        this.character = c;
    }

    @Override
    protected void printThisBefore() {
        System.out.print(character);
    }
}

public class Word extends LetterComposite {

    public Word(List<Letter> letters) {
        letters.forEach(this::add);
    }

    public Word(char... letters) {
        for (char letter : letters) {
            this.add(new Letter(letter));
        }
    }

    @Override
    protected void printThisBefore() {
        System.out.print(" ");
    }
}

public class Sentence extends LetterComposite {

    public Sentence(List<Word> words) {
        words.forEach(this::add);
    }

    @Override
    protected void printThisAfter() {
        System.out.print(".");
    }
}

لدينا الآن مرسل لنقل الرسائل:

public class Messenger {

    LetterComposite messageFromOrcs() {

        var words = List.of(
                new Word('W', 'h', 'e', 'r', 'e'),
                new Word('t', 'h', 'e', 'r', 'e'),
                new Word('i', 's'),
                new Word('a'),
                new Word('w', 'h', 'i', 'p'),
                new Word('t', 'h', 'e', 'r', 'e'),
                new Word('i', 's'),
                new Word('a'),
                new Word('w', 'a', 'y')
        );

        return new Sentence(words);

    }

    LetterComposite messageFromElves() {

        var words = List.of(
                new Word('M', 'u', 'c', 'h'),
                new Word('w', 'i', 'n', 'd'),
                new Word('p', 'o', 'u', 'r', 's'),
                new Word('f', 'r', 'o', 'm'),
                new Word('y', 'o', 'u', 'r'),
                new Word('m', 'o', 'u', 't', 'h')
        );

        return new Sentence(words);

    }

}

وبالتالي يمكن استخدامه كالتالي:

var messenger=new Messenger();

        LOGGER.info("Message from the orcs: ");
        messenger.messageFromOrcs().print();

        LOGGER.info("Message from the elves: ");
        messenger.messageFromElves().print();

مخرجات وحدة التحكم:

Message from the orcs: 
 Where there is a whip there is a way.
Message from the elves: 
 Much wind pours from your mouth.

Diagrama de clases

alt text

Applicabilidad

استخدم نمط Composite عندما:

  • ترغب في تمثيل الهياكل الجزئية للأشياء.
  • ترغب في أن يتجاهل العملاء الفرق بين تراكيب الأشياء والأشياء الفردية. سيعالج العملاء جميع الكائنات في الهيكل المركب بشكل موحد.

الاستخدامات المعروفة

  • واجهات المستخدم الرسومية حيث يمكن للمكونات أن تحتوي على مكونات أخرى (مثل الألواح التي تحتوي على أزرار، تسميات، وألواح أخرى).
  • تمثيلات أنظمة الملفات حيث يمكن للأدلة أن تحتوي على ملفات وأدلة أخرى.
  • الهياكل التنظيمية حيث يمكن للقسم أن يحتوي على أقسام فرعية وموظفين.
  • java.awt.Container و java.awt.Component
  • شجرة المكونات Apache Wicket، انظر Component و MarkupContainer

العواقب

الفوائد:

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

العيوب:

  • قد يجعل التصميم عامًا جدًا. قد يكون من الصعب تقييد مكونات المركب.
  • قد يصعب تحديد أنواع المكونات في المركب.

الأنماط المتعلقة

  • Flyweight: يمكن لـ Composite استخدام Flyweight لمشاركة مثيلات المكونات بين عدة مركبات.
  • Iterador: يمكن استخدامه لتصفح الهياكل المركبة.
  • Visitante: يمكن تطبيق عملية على الهيكل المركب.

الائتمانات