Menu
Coddy logo textTech

Arayüz Tasarımı

Coddy'nin Python Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 26 / 64.

Bir arayüz (interface), sınıfların uyması gereken bir sözleşme tanımlar. Python'da arayüzleri, tüm metotların soyut (abstract) olduğu soyut temel sınıfları (abstract base classes) kullanarak oluştururuz.

abc modülünü içe aktarın:

from abc import ABC, abstractmethod

Yalnızca soyut metotlara sahip bir arayüz oluşturun:

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

Bir arayüzdeki (interface) tüm metotlar soyut (abstract) olmalıdır; bunlar, uygulayan sınıfların ne yapması gerektiğini tanımlar, nasıl yapacaklarını değil.

Arayüzü somut bir sınıfta uygulayın:

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}"

Aynı arayüzü uygulayan başka bir sınıf oluşturun:

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}"

Arayüzü polimorfik olarak kullanın:

shapes = [Circle(5), Rectangle(3, 4)]

for shape in shapes:
    print(shape.draw())
    print(shape.resize(10, 8))

Çıktı:

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

Arayüzleri tür ipucu olarak da kullanabilirsiniz:

def render_shape(drawable: Drawable):
    return drawable.draw()

circle = Circle(3)
print(render_shape(circle))

Çıktı:

Drawing a circle

Önemli Nokta: Arayüzler (Interfaces), sınıfların ne yapması gerektiğini tanımlar, nasıl yapacaklarını değil. Uygulayan sınıfların uyması gereken net sözleşmeler oluşturmak için yalnızca abstract metotlara sahip abstract temel sınıflar kullanın. Bu, farklı uygulamalar arasında tutarlı bir davranış sağlar.

challenge icon

Görev

Orta

Bu meydan okumada, arayüzlere sahip bir medya oynatıcı sistemi uygulayacaksınız.

Aşağıdaki dosyaları düzenlemeniz gerekiyor:

  • playable.py - Soyut temel sınıfları (arayüzleri) uygulayın
  • song.py - Song sınıfını uygulayın
  • video.py - Video sınıfını uygulayın
  • mediaplayer.py - MediaPlayer sınıfını uygulayın

Her dosya, uygulamanıza rehberlik edecek ayrıntılı TODO yorumları içerir. Uygun kalıtım ve arayüz uygulamasına sahip eksiksiz bir medya oynatıcı sistemi oluşturmak için bu yorumları takip edin.

Kopya kağıdı

abc modülünü kullanarak soyut temel sınıflar ile arayüzler oluşturun:

from abc import ABC, abstractmethod

Sadece soyut metotlara sahip bir arayüz tanımlayın:

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

Arayüzü somut sınıflarda uygulayın:

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}"

Arayüzleri polimorfik (çok biçimli) olarak kullanın:

shapes = [Circle(5), Rectangle(3, 4)]

for shape in shapes:
    print(shape.draw())
    print(shape.resize(10, 8))

Arayüzleri tip ipuçları (type hints) olarak kullanın:

def render_shape(drawable: Drawable):
    return drawable.draw()

Arayüzler, sınıfların ne yapması gerektiğini tanımlar, nasıl yapacaklarını değil. Bir arayüzdeki tüm metotlar, uygulayan sınıflar için net sözleşmeler oluşturmak amacıyla soyut olmalıdır.

Kendin dene

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

# Kapsamlı test durumu işleyicisi
test_case = input()

if test_case == "default_test":
    # Orijinal problemden varsayılan test durumu
    song = Song("Bohemian Rhapsody", "Queen", 355)
    video = Video("Python Tutorial", "1080p", 1800)
    player = MediaPlayer()

    # Şarkı ile test et
    player.set_media(song)
    print(player.current_media.get_info())
    print(player.play())
    print(player.pause())
    print(player.stop())
    print()  # Okunabilirlik için boş satır

    # Video ile test et
    player.set_media(video)
    print(player.current_media.get_info())
    print(player.play())
    print(player.pause())
    print(player.stop())

elif test_case == "empty_player":
    # Medya ayarlanmamış medya oynatıcıyı test et
    player = MediaPlayer()
    print(player.play())  # "No media set" yazdırmalı
    print(player.pause())  # "No media set" yazdırmalı
    print(player.stop())  # "No media set" yazdırmalı

elif test_case == "time_formatting":
    # get_info() metodundaki zaman formatlamasını test et
    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 ve Video sınıflarının arayüzleri düzgün uyguladığını test et
    song = Song("Test Song", "Test Artist", 180)
    video = Video("Test Video", "480p", 240)
    
    # Arayüz uygulamasını kontrol et
    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)}")
    
    # Tüm arayüz metodlarını test et
    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":
    # Farklı medya türlerinden oluşan bir liste ile polimorfik davranışı test et
    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":
    # Uç durumları test et
    empty_song = Song("", "", 0)
    edge_video = Video("A" * 100, "", -10)  # Çok uzun başlık, boş çözünürlük, negatif süre
    
    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":
    # Birçok medya nesnesi ile stres testi uygula
    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()
    
    # Tüm şarkılarla test et
    for i, song in enumerate(songs):
        player.set_media(song)
        if i % 10 == 0:  # Çok fazla çıktıdan kaçınmak için sadece her 10. şarkıyı yazdır
            print(f"Playing song {i+1}: {player.play()}")
    
    # Tüm videolarla test et
    for i, video in enumerate(videos):
        player.set_media(video)
        if i % 10 == 0:  # Çok fazla çıktıdan kaçınmak için sadece her 10. videoyu yazdır
            print(f"Playing video {i+1}: {player.play()}")
    
    print("Stress test completed successfully!")
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Object Oriented Programming bölümündeki tüm dersler