Menu
CoddyTech
flag Ar iconالعربيةdown icon

تصميم الواجهات

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

تُعرِّف الواجهة عقدًا يجب أن تلتزم به الفئات. في Python، ننشئ الواجهات باستخدام الفئات الأساسية المجرّدة، حيث تكون جميع الأساليب مجرّدة.

استورد الوحدة abc:

from abc import ABC, abstractmethod

أنشئ واجهة تحتوي على أساليب مجردة فقط:

class Drawable(ABC):
    @abstractmethod
    def draw(self):
        pass
    @abstractmethod
    def resize(self, width, height):
        pass

يجب أن تكون جميع الأساليب في الواجهة مجردة - فهي تحدد ما يجب على الفئات المُنفِّذة فعله، وليس كيفية فعله.

نفِّذ الواجهة في فئة ملموسة:

class Circle(Drawable):
    def __init__(self, radius):
        self.radius = radius
    def draw(self):
        return "Drawing a circle"
    def resize(self, width, height):
        self.radius = min(width, height) / 2
        return f"Resized circle to radius {self.radius}"

أنشئ فئة أخرى تنفّذ الواجهة نفسها:

class Rectangle(Drawable):
    def __init__(self, width, height):
        self.width = width
        self.height = height
    def draw(self):
        return "Drawing a rectangle"
    def resize(self, width, height):
        self.width = width
        self.height = height
        return f"Resized rectangle to {width}x{height}"

استخدم الواجهة بشكل تعددي الأشكال:

shapes = [Circle(5), Rectangle(3, 4)]
for shape in shapes:
    print(shape.draw())
    print(shape.resize(10, 8))

المخرجات:

Drawing a circle
Resized circle to radius 4.0
Drawing a rectangle
Resized rectangle to 10x8

يمكنك أيضًا استخدام الواجهات كتلميحات للأنواع:

def render_shape(drawable: Drawable):
    return drawable.draw()
circle = Circle(3)
print(render_shape(circle))

المخرجات:

Drawing a circle

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

challenge icon

التحدي

متوسط

في هذا التحدي، ستنفّذ نظام مشغّل وسائط باستخدام الواجهات.

تحتاج إلى تعديل الملفات التالية:

  • playable.py - تنفيذ الفئات الأساسية المجرّدة (الواجهات)
  • song.py - تنفيذ الفئة Song
  • video.py - تنفيذ الفئة Video
  • mediaplayer.py - تنفيذ الفئة MediaPlayer

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

REQUIRED OUTPUT FORMAT: [Your translated content here]

جرّب بنفسك

from song import Song
from video import Video
from mediaplayer import MediaPlayer
from playable import Playable, MediaInfo

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

if test_case == "default_test":
    # حالة الاختبار الافتراضية من المسألة الأصلية
    song = Song("Bohemian Rhapsody", "Queen", 355)
    video = Video("Python Tutorial", "1080p", 1800)
    player = MediaPlayer()

    # اختبار مع الأغنية
    player.set_media(song)
    print(player.current_media.get_info())
    print(player.play())
    print(player.pause())
    print(player.stop())
    print()  # سطر فارغ لسهولة القراءة

    # اختبار مع الفيديو
    player.set_media(video)
    print(player.current_media.get_info())
    print(player.play())
    print(player.pause())
    print(player.stop())

elif test_case == "empty_player":
    # اختبار مشغل الوسائط بدون تعيين أي وسائط
    player = MediaPlayer()
    print(player.play())  # Should print "No media set"
    print(player.pause())  # Should print "No media set"
    print(player.stop())  # Should print "No media set"

elif test_case == "time_formatting":
    # اختبار تنسيق الوقت في الدالة get_info()
    song1 = Song("Short Song", "Artist A", 65)  # 1:05
    song2 = Song("Long Song", "Artist B", 3661)  # 61:01
    video1 = Video("Hour Video", "720p", 3600)  # 60:00
    
    print(song1.get_info())
    print(song2.get_info())
    print(video1.get_info())

elif test_case == "interface_compliance":
    # اختبار أن Song و Video ينفذان الواجهات بشكل صحيح
    song = Song("Test Song", "Test Artist", 180)
    video = Video("Test Video", "480p", 240)
    
    # التحقق من تنفيذ الواجهة
    print(f"Song implements Playable: {isinstance(song, Playable)}")
    print(f"Song implements MediaInfo: {isinstance(song, MediaInfo)}")
    print(f"Video implements Playable: {isinstance(video, Playable)}")
    print(f"Video implements MediaInfo: {isinstance(video, MediaInfo)}")
    
    # اختبار جميع دوال الواجهة
    print(song.play())
    print(song.pause())
    print(song.stop())
    print(song.get_title())
    print(song.get_duration())
    print(song.get_info())
    
    print(video.play())
    print(video.pause())
    print(video.stop())
    print(video.get_title())
    print(video.get_duration())
    print(video.get_info())

elif test_case == "polymorphism":
    # اختبار السلوك متعدد الأشكال مع قائمة من أنواع وسائط مختلفة
    media_list = [
        Song("Song 1", "Artist 1", 180),
        Video("Video 1", "720p", 300),
        Song("Song 2", "Artist 2", 240),
        Video("Video 2", "1080p", 420)
    ]
    
    player = MediaPlayer()
    
    for media in media_list:
        player.set_media(media)
        print(f"Media: {media.get_title()}")
        print(f"Info: {media.get_info()}")
        print(f"Play: {player.play()}")
        print()

elif test_case == "edge_cases":
    # اختبار الحالات الحدية
    empty_song = Song("", "", 0)
    edge_video = Video("A" * 100, "", -10)  # عنوان طويل جدًا، دقة فارغة، مدة سالبة
    
    print(f"Empty song info: {empty_song.get_info()}")
    print(f"Edge video info: {edge_video.get_info()}")
    
    player = MediaPlayer()
    player.set_media(empty_song)
    print(player.play())
    player.set_media(edge_video)
    print(player.play())

elif test_case == "stress_test":
    # تنفيذ اختبار إجهاد مع العديد من كائنات الوسائط
    songs = [Song(f"Song {i}", f"Artist {i}", i * 30) for i in range(1, 101)]
    videos = [Video(f"Video {i}", f"{i*10}p", i * 60) for i in range(1, 101)]
    
    player = MediaPlayer()
    
    # اختبار مع جميع الأغاني
    for i, song in enumerate(songs):
        player.set_media(song)
        if i % 10 == 0:  # اطبع فقط كل عاشر لتجنب الكثير من المخرجات
            print(f"Playing song {i+1}: {player.play()}")
    
    # اختبار مع جميع مقاطع الفيديو
    for i, video in enumerate(videos):
        player.set_media(video)
        if i % 10 == 0:  # اطبع فقط كل عاشر لتجنب الكثير من المخرجات
            print(f"Playing video {i+1}: {player.play()}")
    
    print("Stress test completed successfully!")
quiz iconاختبر نفسك

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

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

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