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

نمط المحول

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

يُعد نمط Adapter نمطًا هيكليًا لتصميم البرمجيات يتيح للواجهات غير المتوافقة العمل معًا. ويعمل كجسر بين فئتين، إذ يحوّل واجهة إحدى الفئتين إلى واجهة يتوقعها العميل. فكّر فيه كمحوّل طاقة يتيح لك توصيل جهاز أوروبي بمقبس أمريكي.

تخيّل أن لديك واجهة MediaPlayer موجودة تشغّل ملفات صوتية، لكنك تحتاج إلى دمج مكتبة تابعة لجهة خارجية تستخدم واجهة مختلفة تمامًا لتشغيل مقاطع الفيديو:

// الواجهة الحالية التي يستخدمها الكود الخاص بك
interface MediaPlayer {
    void play(String filename);
}

// فئة من طرف ثالث ذات واجهة غير متوافقة
class AdvancedVideoPlayer {
    public void playVideo(String filename) {
        System.out.println("Playing video: " + filename);
    }
}

يقوم adapter بتغليف class الـincompatible ويستخدم implements لتطبيق الواجهة interface المتوقعة، ويترجم الاستدعاءات بينهما:

class VideoPlayerAdapter implements MediaPlayer {
    private AdvancedVideoPlayer videoPlayer;
    
    public VideoPlayerAdapter() {
        this.videoPlayer = new AdvancedVideoPlayer();
    }
    
    public void play(String filename) {
        videoPlayer.playVideo(filename);
    }
}

يمكن لرمز العميل الآن استخدام مشغّل الفيديو من خلال الواجهة المألوفة MediaPlayer:

MediaPlayer player = new VideoPlayerAdapter();
player.play("movie.mp4");  // المخرجات: تشغيل الفيديو: movie.mp4

يُعد نمط Adapter ذا قيمة كبيرة عند دمج الشيفرة legacy أو مكتبات الجهات الخارجية دون تعديل شيفرتها المصدرية. يظل Client غير مدرك أنه يتعامل مع فئة خضعت للتكييف. فهو يستخدم ببساطة الواجهة التي يعرفها.

challenge icon

التحدي

سهل

لنبنِ نظامًا لتحويل درجات الحرارة باستخدام نمط Adapter! لديك تطبيق طقس موجود يعمل بدرجات حرارة بوحدة Celsius، لكنك تحتاج إلى دمج مستشعر درجة حرارة legacy لا يُخرج إلا قراءات بوحدة Fahrenheit. وبدلًا من تعديل أيٍّ من النظامين، ستنشئ adapter يصل بينهما.

ستنظّم التعليمات البرمجية عبر أربعة ملفات:

  • TemperatureProvider.java: عرّف الواجهة التي يتوقعها تطبيق الطقس. يجب أن تعلن عن أسلوب getTemperatureCelsius() يُرجع قيمة double تمثّل درجة الحرارة بوحدة Celsius.
  • FahrenheitSensor.java: يمثّل هذا المستشعر legacy ذا الواجهة غير المتوافقة. أنشئ class يحتوي على field خاص من النوع double لدرجة الحرارة بوحدة Fahrenheit، ويتم تعيينه عبر constructor. ويجب أن يحتوي على أسلوب readFahrenheit() يُرجع قيمة Fahrenheit المخزّنة.
  • SensorAdapter.java: أنشئ adapter يجعل مستشعر Fahrenheit متوافقًا مع تطبيق الطقس. يجب أن يقوم adapter بتنفيذ TemperatureProvider ولفّ كائن FahrenheitSensor. عند استدعاء getTemperatureCelsius()، يجب أن يقرأ من المستشعر ويحوّل القيمة إلى Celsius باستخدام الصيغة: (fahrenheit - 32) * 5 / 9.
  • Main.java: اجمع كل شيء معًا! ستتلقى input واحدًا: قراءة درجة حرارة بوحدة Fahrenheit (double).

    أنشئ FahrenheitSensor باستخدام قيمة input. ثم أنشئ SensorAdapter يلفّ هذا المستشعر. خزّن adapter في متغير من النوع TemperatureProvider لإثبات أن تطبيق الطقس يمكنه استخدامه من خلال الواجهة المتوقعة.

    اطبع النتيجة بهذا التنسيق: Temperature: [celsius] C حيث تُنسّق celsius إلى منزلة عشرية واحدة.

ستتلقى input واحدًا: درجة الحرارة بوحدة Fahrenheit (double).

على سبيل المثال، عند إدخال 98.6، سيكون الخرج كما يلي:

Temperature: 37.0 C

لاحظ كيف يعمل class ‏Main بالكامل باستخدام واجهة TemperatureProvider. فهو لا يعرف أن درجة الحرارة الفعلية تأتي من مستشعر Fahrenheit تتم مواءمته خلف الكواليس. هذه هي روعة نمط Adapter!

جرّب بنفسك

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        double fahrenheit = scanner.nextDouble();
        
        // TODO: إنشاء FahrenheitSensor باستخدام القيمة المدخلة
        
        // TODO: إنشاء SensorAdapter يقوم بتغليف الـ sensor
        
        // TODO: تخزين الـ adapter في متغير TemperatureProvider
        
        // TODO: الحصول على درجة الحرارة بالسيلسيوس وطباعتها
        // التنسيق: "Temperature: [celsius] C" مع خانة عشرية واحدة
        // تلميح: استخدم String.format("%.1f", value) للتنسيق
    }
}
quiz iconاختبر نفسك

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

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

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