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

نمط المحول

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

يسمح نمط المُحوِّل للكائنات ذات الواجهات غير المتوافقة بالعمل معًا. ويعمل كجسر من خلال تغليف فئة موجودة بواجهة جديدة يتوقعها العملاء.

إليك نظامان بواجهات غير متوافقة:

class OldPrinter:
    def old_print(self, text):
        return f"OLD: {text}"

class NewPrinter:
    def print(self, text):
        return f"NEW: {text}"

تستخدم الطابعة القديمة old_print() بينما تستخدم الطابعة الجديدة print().

أنشئ محوّلًا لجعل الطابعة القديمة تعمل مع الواجهة الجديدة:

class PrinterAdapter:
    def __init__(self, old_printer):
        self.old_printer = old_printer
    
    def print(self, text):
        # تكييف الواجهة القديمة إلى الواجهة الجديدة
        return self.old_printer.old_print(text)

يقوم المهايئ بتغليف الطابعة القديمة ويوفّر الواجهة المتوقعة.

استخدم كلتا الطابعتين مع رمز العميل نفسه:

def print_document(printer, text):
    return printer.print(text)  # يتوقع method print()

# استخدم الطابعة الجديدة مباشرة
new_printer = NewPrinter()
print(print_document(new_printer, "Hello"))

# استخدم الطابعة القديمة من خلال المحول
old_printer = OldPrinter()
adapter = PrinterAdapter(old_printer)
print(print_document(adapter, "Hello"))

أنشئ مثالًا آخر باستخدام مشغلات الوسائط:

class Mp3Player:
    def play_mp3(self, filename):
        return f"Playing MP3: {filename}"

class Mp4Player:
    def play_mp4(self, filename):
        return f"Playing MP4: {filename}"

class MediaAdapter:
    def __init__(self, player, audio_type):
        self.player = player
        self.audio_type = audio_type
    
    def play(self, filename):
        if self.audio_type == "mp3":
            return self.player.play_mp3(filename)
        elif self.audio_type == "mp4":
            return self.player.play_mp4(filename)
class AudioPlayer:
    def play(self, audio_type, filename):
        if audio_type == "mp3":
            return Mp3Player().play_mp3(filename)
        else:
            adapter = MediaAdapter(Mp4Player(), audio_type)
            return adapter.play(filename)

player = AudioPlayer()
print(player.play("mp3", "song.mp3"))
print(player.play("mp4", "video.mp4"))

المخرجات:

NEW: Hello
OLD: Hello
Playing MP3: song.mp3
Playing MP4: video.mp4

النقطة الأساسية: يجعل نمط المحوِّل الواجهات غير المتوافقة تعمل معًا من خلال تغليف فئة موجودة بواجهة جديدة. يترجم المحوِّل الاستدعاءات من الواجهة المتوقعة إلى الواجهة الفعلية للكائن المُغلَّف. يكون هذا مفيدًا لدمج التعليمات البرمجية القديمة أو مكتبات الجهات الخارجية دون تعديل التعليمات البرمجية الموجودة.

challenge icon

التحدي

متوسط

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

 

لدى شركتك نظام قديم لتحليل البيانات وتصورها، ويحتاج إلى دمجه مع منصة تحليلات حديثة جديدة. تحتوي المكونات القديمة على واجهات غير متوافقة مع النظام الجديد. وبدلًا من إعادة كتابة الشيفرة القديمة (وهو ما سيكون محفوفًا بالمخاطر ومكلفًا)، كُلّفت بإنشاء محوّلات لجعل هذه المكونات تعمل مع النظام الجديد.

تحتاج إلى:

  1. فهم الواجهات الحديثة المعرّفة في interfaces.py (لا يمكن تعديل هذا الملف)
  2. فحص المكونات القديمة في legacy_system.py (لا يمكن تعديل هذا الملف)
  3. تنفيذ فئات المحوّلات في adapters.py لجعل المكونات القديمة متوافقة مع الواجهات الحديثة
  4. إنشاء نظام حديث في modern_system.py يستخدم هذه الواجهات
REQUIRED OUTPUT FORMAT: [Your translated content here]

جرّب بنفسك

# استيراد جميع الفئات الضرورية
from adapters import LegacyDataAnalyzerAdapter, LegacyChartGeneratorAdapter
from modern_system import AnalyticsSystem

# معالج حالات الاختبار الشامل
test_case = input()

if test_case == "basic_adapter_test":
    # اختبار وظائف المحول الأساسية
    processor = LegacyDataAnalyzerAdapter()
    data = [1, 2, 3, 4, 5]
    processor.process_data(data)
    results = processor.get_results()
    print(f"Results: {results}")

elif test_case == "visualizer_adapter_test":
    # اختبار محول العارض المرئي
    visualizer = LegacyChartGeneratorAdapter("bar")
    data = [10, 20, 30, 40, 50]
    success = visualizer.visualize(data)
    if success:
        export_success = visualizer.export_visualization("test_chart.png")
        print(f"Visualization exported: {export_success}")

elif test_case == "analytics_system_test":
    # اختبار نظام التحليلات الكامل
    processor = LegacyDataAnalyzerAdapter()
    visualizer = LegacyChartGeneratorAdapter("line")
    system = AnalyticsSystem(processor, visualizer)
    
    data = [15, 25, 35, 45, 55]
    result = system.analyze_and_visualize(data, "analytics_output.png")
    print(f"System result: {result}")

elif test_case == "validation_error_test":
    # Test validation errors
    processor = LegacyDataAnalyzerAdapter()
    try:
        processor.process_data("invalid_data")
        print("Validation failed - should have raised ValueError")
    except ValueError as e:
        print(f"Validation error caught: {e}")

elif test_case == "empty_data_test":
    # اختبار مع بيانات فارغة
    processor = LegacyDataAnalyzerAdapter()
    try:
        processor.process_data([])
        results = processor.get_results()
        print(f"Empty data results: {results}")
    except Exception as e:
        print(f"Empty data error: {e}")

elif test_case == "chart_types_test":
    # اختبار أنواع المخططات المختلفة
    chart_types = ["bar", "line", "pie"]
    data = [5, 15, 25, 35]
    
    for chart_type in chart_types:
        visualizer = LegacyChartGeneratorAdapter(chart_type)
        success = visualizer.visualize(data)
        print(f"{chart_type} chart created: {success}")

elif test_case == "file_extension_test":
    # اختبار معالجة امتدادات الملفات
    visualizer = LegacyChartGeneratorAdapter()
    data = [1, 2, 3, 4]
    visualizer.visualize(data)
    
    # اختبار تنسيقات أسماء الملفات المختلفة
    filenames = ["test", "test.jpg", "test.pdf", "test.png"]
    for filename in filenames:
        success = visualizer.export_visualization(filename)
        print(f"Export '{filename}': {success}")

elif test_case == "summary_test":
    # Test analysis summary
    processor = LegacyDataAnalyzerAdapter()
    visualizer = LegacyChartGeneratorAdapter()
    system = AnalyticsSystem(processor, visualizer)
    
    data = [10, 20, 30, 40, 50, 60]
    system.analyze_and_visualize(data)
    summary = system.get_analysis_summary()
    print("Analysis Summary:")
    print(summary)

elif test_case == "mixed_data_test":
    # اختبار مع بيانات رقمية مختلطة
    processor = LegacyDataAnalyzerAdapter()
    data = [1.5, 2, 3.7, 4, 5.2]
    processor.process_data(data)
    results = processor.get_results()
    print(f"Mixed data results: {results}")

elif test_case == "invalid_numeric_test":
    # اختبار مع بيانات رقمية غير صالحة
    processor = LegacyDataAnalyzerAdapter()
    try:
        processor.process_data([1, 2, "three", 4, 5])
        print("Validation failed - should have raised ValueError")
    except ValueError as e:
        print(f"Invalid numeric data error: {e}")

elif test_case == "no_results_summary_test":
    # اختبار الملخص بدون نتائج
    processor = LegacyDataAnalyzerAdapter()
    visualizer = LegacyChartGeneratorAdapter()
    system = AnalyticsSystem(processor, visualizer)
    
    summary = system.get_analysis_summary()
    print(f"No results summary: {summary}")

elif test_case == "large_dataset_test":
    # اختبار مع مجموعة بيانات أكبر
    processor = LegacyDataAnalyzerAdapter()
    data = list(range(1, 101))  # من 1 إلى 100
    processor.process_data(data)
    results = processor.get_results()
    print(f"Large dataset - Mean: {results.get('mean', 'N/A'):.2f}")
    print(f"Large dataset - Min: {results.get('min', 'N/A')}")
    print(f"Large dataset - Max: {results.get('max', 'N/A')}")

elif test_case == "complete_workflow_test":
    # Test complete workflow with multiple operations
    processor = LegacyDataAnalyzerAdapter()
    bar_visualizer = LegacyChartGeneratorAdapter("bar")
    line_visualizer = LegacyChartGeneratorAdapter("line")
    
    data = [12, 18, 25, 32, 28, 35, 42]
    
    # إنشاء أنظمة تحليلات مع أدوات تصور مختلفة
    bar_system = AnalyticsSystem(processor, bar_visualizer)
    line_system = AnalyticsSystem(LegacyDataAnalyzerAdapter(), line_visualizer)
    
    # تشغيل التحليلات
    bar_result = bar_system.analyze_and_visualize(data, "bar_chart.png")
    line_result = line_system.analyze_and_visualize(data, "line_chart.png")
    
    print("Complete workflow test completed")
    print(f"Bar chart result: {bar_result['visualization_file']}")
    print(f"Line chart result: {line_result['visualization_file']}")
    
    # الحصول على الملخصات
    print("Bar system summary:")
    print(bar_system.get_analysis_summary())
    print("Line system summary:")
    print(line_system.get_analysis_summary())
quiz iconاختبر نفسك

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

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

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