أنماط التصميم المتقدمة في Java: من Bridge إلى Visitor
\n\nأنماط التصميم هي حلول مجربة للمشكلات النمطية في بنية البرمجيات. إذا كانت الأنماط الأساسية (Singleton، Factory، Observer) مألوفة لكل مطور Java، فإن الأنماط المتقدمة غالبًا ما تبقى خلف الكواليس. في هذه المقالة، سنشرح ثلاثة أنماط قوية: Bridge وVisitor وMemento. ستتعرف على متى يتم تطبيقها، وستحصل على أمثلة جاهزة للكود بلغة Java.
\n\n1. Bridge (الجسر) — فصل التجريد عن التنفيذ
\n\nيُستخدم نمط Bridge عندما تحتاج إلى فصل التجريد عن تنفيذه، بحيث يمكن لكل منهما التغير بشكل مستقل. هذا مفيد بشكل خاص عندما يكون لديك عدة أبعاد للتغيير (مثل أنواع مختلفة من الأجهزة وأجهزة تحكم مختلفة).
\n\nمتى يتم التطبيق: عندما تريد تجنب "انفجار الفئات" بسبب الجمع بين الخيارات المختلفة.
\n\nمثال: التحكم في الأجهزة
\n\nتخيل أن لدينا أجهزة تحكم (Remote) وأجهزة (Device). نريد أن يعمل جهاز تحكم واحد مع أجهزة مختلفة (TV، Radio).
\n\n// التنفيذ (Device)\ninterface Device {\n void turnOn();\n void turnOff();\n void setVolume(int percent);\n}\n\nclass TV implements Device {\n @Override\n public void turnOn() { System.out.println("TV قيد التشغيل"); }\n @Override\n public void turnOff() { System.out.println("TV متوقف"); }\n @Override\n public void setVolume(int percent) { System.out.println("مستوى صوت TV: " + percent + "%"); }\n}\n\nclass Radio implements Device {\n @Override\n public void turnOn() { System.out.println("Radio قيد التشغيل"); }\n @Override\n public void turnOff() { System.out.println("Radio متوقف"); }\n @Override\n public void setVolume(int percent) { System.out.println("مستوى صوت Radio: " + percent + "%"); }\n}\n\n// التجريد (Remote)\nabstract class Remote {\n protected Device device;\n\n public Remote(Device device) {\n this.device = device;\n }\n\n public abstract void togglePower();\n public abstract void volumeUp();\n public abstract void volumeDown();\n}\n\nclass BasicRemote extends Remote {\n private boolean isOn = false;\n private int volume = 10;\n\n public BasicRemote(Device device) {\n super(device);\n }\n\n @Override\n public void togglePower() {\n if (isOn) { device.turnOff(); isOn = false; }\n else { device.turnOn(); isOn = true; }\n }\n\n @Override\n public void volumeUp() {\n volume += 5;\n device.setVolume(volume);\n }\n\n @Override\n public void volumeDown() {\n volume -= 5;\n device.setVolume(volume);\n }\n}\n\n// الاستخدام\npublic class BridgeDemo {\n public static void main(String[] args) {\n Device tv = new TV();\n Remote remote = new BasicRemote(tv);\n remote.togglePower(); // TV قيد التشغيل\n remote.volumeUp(); // مستوى صوت TV: 15%\n\n Device radio = new Radio();\n remote = new BasicRemote(radio);\n remote.togglePower(); // Radio قيد التشغيل\n remote.volumeUp(); // مستوى صوت Radio: 15%\n }\n}\n\nالميزة: يمكننا إضافة أنواع جديدة من الأجهزة أو أجهزة تحكم جديدة دون تغيير الكود الموجود. نمط Bridge مثالي للتطبيقات عبر المنصات (مثل واجهة المستخدم على أنظمة تشغيل مختلفة).
\n\n2. Visitor (الزائر) — عمليات جديدة دون تغيير الفئات
\n\nيسمح نمط Visitor بإضافة عمليات جديدة إلى مجموعة من الكائنات دون تغيير فئات هذه الكائنات نفسها. هذه طريقة تقليدية لتجاوز قيود الإرسال الفردي في Java.
\n\nمتى يتم التطبيق: عندما يكون لديك تسلسل هرمي ثابت للفئات، ولكنك تضيف عمليات جديدة بشكل متكرر (مثل التصدير إلى تنسيقات مختلفة، إنشاء التقارير).
\n\nمثال: تصدير الأشكال إلى تنسيقات مختلفة
\n\nلدينا أشكال