ISP — τι είναι, αρχή διαχωρισμού διεπαφών στην ανάπτυξη

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-05-12 Χρόνος ανάγνωσης: 9 λεπ

ISP (Interface Segregation Principle) — η τέταρτη αρχή SOLID που δηλώνει: οι πελάτες δεν πρέπει να εξαρτώνται από μεθόδους που δεν χρησιμοποιούν. Η αρχή διατυπώθηκε από τον Robert Martin στο πλαίσιο σχεδιασμού διεπαφών για αντικειμενοστραφή συστήματα. Όπως περιγράφεται στο βιβλίο Clean Architecture (2017), η αρχή διαχωρισμού διεπαφών απαιτεί τη δημιουργία στενά εξειδικευμένων διεπαφών αντί για μία καθολική, μειώνοντας τη σύζευξη και απλοποιώντας την πραγματοποίηση αλλαγών.

Κύρια Σημεία

  • ISP — αρχή διαχωρισμού διεπαφών, τέταρτη στο SOLID
  • Πελάτες δεν πρέπει να εξαρτώνται από μεθόδους που δεν καλούν
  • Παχιές διεπαφές (Fat Interfaces) περιέχουν μεθόδους μη σχετικές για μέρος των πελατών
  • Διάσπαση διεπαφών μειώνει τη σύζευξη και αυξάνει την επαναχρησιμοποίηση κώδικα
  • Το ISP συνδέεται στενά με το SRP και το Single Responsibility σε επίπεδο διεπαφών

Τι είναι το ISP (Interface Segregation Principle);

ISP (Interface Segregation Principle) — η αρχή διαχωρισμού διεπαφών που απαγορεύει τη δημιουργία “παχιών” διεπαφών με μεθόδους που δεν χρησιμοποιούνται από όλους τους πελάτες. Αντί για μία διεπαφή με δέκα μεθόδους, σχεδιάζονται πολλές μικρές διεπαφές, κάθε μία για τη δική της ομάδα πελατών.

Η αρχή εισήχθη από τον Robert Martin ως λύση στο πρόβλημα της “μόλυνσης διεπαφών”, όταν μια κλάση αναγκάζεται να υλοποιήσει μεθόδους που δεν χρειάζεται μόνο και μόνο επειδή δηλώνονται σε μια κοινή διεπαφή. Σε στατικά τυποποιημένες γλώσσες, αυτό οδηγεί σε κενές υλοποιήσεις ή ρίψη εξαιρέσεων — άμεσο σημάδι παραβίασης του ISP.

ISP και SRP αλληλοσυμπληρώνονται: το SRP αφορά την ευθύνη της κλάσης, το ISP αφορά τα συμβόλαια των διεπαφών. Το SRP λέει “μία κλάση — ένας λόγος για αλλαγή”, το ISP λέει “μία διεπαφή — ένα σενάριο πελάτη”. Μαζί σχηματίζουν μια αρθρωτή αρχιτεκτονική όπου κάθε στοιχείο του συστήματος έχει σαφή όρια.

Παχιές διεπαφές και οι συνέπειές τους

Fat Interface — μια διεπαφή που περιέχει περισσότερες μεθόδους από όσες χρειάζεται ένας συγκεκριμένος πελάτης. Για παράδειγμα, η διεπαφή Worker με μεθόδους work, eat, sleep. Ένας ρομπότ-εργάτης δεν θα έπρεπε να υλοποιεί τις eat και sleep, αλλά αναγκάζεται. Λύση — διαχωρισμός σε Workable, Eatable, Sleepable. Κάθε πελάτης λαμβάνει ακριβώς ό,τι χρειάζεται.

Στην κινητή ανάπτυξη, οι παχιές διεπαφές εμφανίζονται σε πρωτόκολλα εκπροσώπων και DataSource. Ένα πρωτόκολλο μπορεί να περιέχει μεθόδους για δύο διαφορετικά σενάρια (επεξεργασία + προβολή), αν και μια συγκεκριμένη οθόνη χρησιμοποιεί μόνο ένα από αυτά.

Πώς λειτουργεί η αρχή διαχωρισμού διεπαφών

Η υλοποίηση του ISP ξεκινά με ανάλυση των πελατών κάθε διεπαφής. Εάν δύο πελάτες χρησιμοποιούν διαφορετικά σύνολα μεθόδων της ίδιας διεπαφής — η διεπαφή πρέπει να διαχωριστεί. Κάθε νέα διεπαφή ομαδοποιεί μεθόδους που καλούνται μαζί στο πλαίσιο ενός σεναρίου.

Μηχανισμός διαχωρισμού: η αρχική διεπαφή χωρίζεται σε πολλές στενές διεπαφές, κάθε μία κληρονομώντας το κοινό μέρος (εάν υπάρχει). Οι πελάτες μεταβαίνουν σε εξάρτηση από την απαιτούμενη στενή διεπαφή αντί για τη γενική. Οι κλάσεις που υλοποιούσαν την αρχική διεπαφή τώρα υλοποιούν μόνο εκείνες τις στενές διεπαφές που πραγματικά χρειάζονται.

Σημαντική διευκρίνιση: ο βαθμός διάσπασης καθορίζεται από τον αριθμό των πελατών και των σεναρίων τους. Το ISP δεν απαιτεί μέγιστη διάσπαση (μικροδιεπαφές με μία μέθοδο). Αυτό θα οδηγούσε σε υπερβολική πολυπλοκότητα. Στόχος είναι η εξάλειψη της εξάρτησης των πελατών από περιττές μεθόδους, όχι η ελαχιστοποίηση του μεγέθους κάθε διεπαφής.

Σημάδια παραβίασης του ISP

Τα κύρια σημάδια παραβίασης του ISP περιλαμβάνουν: κλάσεις που υλοποιούν μια διεπαφή με κενές μεθόδους (πλασματική υλοποίηση), ρίψη της εξαίρεσης UnsupportedOperationException σε υλοποιήσεις, μεγάλο αριθμό παραμέτρων ή τύπων επιστροφής που δεν χρησιμοποιούνται από μέρος των πελατών και συχνές αλλαγές διεπαφής που επηρεάζουν μόνο μέρος των πελατών.

Στην ανάπτυξη Android, ένα τυπικό παράδειγμα παραβίασης του ISP είναι η διεπαφή OnItemClickListener που περιλαμβάνει μεθόδους για κλικ, μακρύ κλικ και σύρσιμο. Εάν μια συγκεκριμένη οθόνη χρησιμοποιεί μόνο κλικ — οι υπόλοιπες μέθοδοι παραμένουν κενές. Λύση — διαχωρισμός σε OnItemClickListener, OnItemLongClickListener, OnItemSwipeListener.

Στην ανάπτυξη iOS, η παραβίαση του ISP εκδηλώνεται σε εκπροσώπους UIKit: ένα πρωτόκολλο περιέχει μεθόδους για διαφορετικές καταστάσεις ενός component. Το UITableViewDelegate περιλαμβάνει μεθόδους για προβολή, επιλογή, επεξεργασία και ενέργειες σύρσιμου. Συχνά οι προγραμματιστές υλοποιούν ολόκληρο το πρωτόκολλο με δέκα κενές μεθόδους. Ο διαχωρισμός σε πολλά πρωτόκολλα ανά ομάδες ευθύνης λύνει το πρόβλημα.

Εξάρτηση από μη χρησιμοποιούμενες μεθόδους

Το πρόβλημα δεν είναι μόνο στην αισθητική του κώδικα. Όταν μια διεπαφή αλλάζει (προστίθεται μια νέα μέθοδος), όλες οι κλάσεις υλοποίησης πρέπει να ενημερωθούν — ακόμα και εκείνες που δεν χρειάζονται τη νέα μέθοδο. Στην κινητή ανάπτυξη με δεκάδες οθόνες, αυτό οδηγεί σε αλυσιδωτές αλλαγές. Το ISP απομονώνει κάθε πελάτη από αλλαγές που δεν τον αφορούν.

Σιωπηρή παραβίαση του ISP συμβαίνει μέσω παραμέτρων διαμόρφωσης. Εάν μια μέθοδος λαμβάνει ένα αντικείμενο με μεγάλο αριθμό πεδίων, ενώ ο πελάτης χρησιμοποιεί μόνο 2-3 από αυτά — αυτό είναι σήμα για διαχωρισμό. Εναλλακτική: πολλές εξειδικευμένες μέθοδοι με ελάχιστο σύνολο παραμέτρων.

Στην ανάπτυξη Android, το ISP παραβιάζεται όταν χρησιμοποιείται ένας μόνο SharedPreferencesManager για ανάγνωση και εγγραφή όλων των ρυθμίσεων της εφαρμογής. Ένα Fragment που χρειάζεται μόνο να διαβάσει το θέμα λαμβάνει εξάρτηση από τον καθολικό διαχειριστή με δεκάδες μεθόδους για διαφορετικούς τύπους δεδομένων. Διαχωρισμός σε ThemePreferenceProvider, AuthPreferenceProvider, FeatureFlagProvider — εφαρμογή του ISP σε επίπεδο υπηρεσιών διαμόρφωσης. Κάθε πάροχος περιέχει ακριβώς τις μεθόδους που χρειάζονται οι πελάτες του.

Παραδείγματα ISP σε κινητές εφαρμογές

Ας εξετάσουμε το παράδειγμα Android με μια διεπαφή για εργασία με δεδομένα. Παραβίαση ISP — μία διεπαφή για όλες τις λειτουργίες CRUD, αν και δεν χρειάζονται όλοι οι πελάτες όλες τις λειτουργίες.

kotlin
// Παραβίαση ISP: παχιά διεπαφή
interface UserRepository {
    fun getAll(): List<User>
    fun getById(id: Int): User
    fun save(user: User)
    fun delete(id: Int)
}

// Μετά από εφαρμογή ISP: στενές διεπαφές
interface UserReader {
    fun getAll(): List<User>
    fun getById(id: Int): User
}

interface UserWriter {
    fun save(user: User)
    fun delete(id: Int)
}

// ReadOnlyViewModel δεν εξαρτάται από μεθόδους εγγραφής
class ReadOnlyViewModel(
    private val reader: UserReader
)

Παράδειγμα iOS με διαχωρισμό πρωτοκόλλων για εργασία με πολυμέσα:

swift
// Παραβίαση ISP: ένα πρωτόκολλο για όλη τη διαχείριση πολυμέσων
protocol MediaService {
    func play(url: URL)
    func pause()
    func stop()
    func upload(data: Data) async -> URL
    func download(url: URL) async -> Data
}

// Μετά ISP: διαχωρισμός σε πρωτόκολλα ανά ευθύνη
protocol MediaPlayer {
    func play(url: URL)
    func pause()
    func stop()
}

protocol MediaTransfer {
    func upload(data: Data) async -> URL
    func download(url: URL) async -> Data
}

// PlayerViewModel δεν εξαρτάται από μεθόδους φόρτωσης
class PlayerViewModel {
    private let player: MediaPlayer
}

Πρακτικό συμπέρασμα: Το ISP προστατεύει τους πελάτες από αλλαγές σε ανεξάρτητα μέρη της διεπαφής. Ο διαχωρισμός του UserRepository σε UserReader και UserWriter σημαίνει ότι οι αλλαγές στο save δεν επηρεάζουν το ReadOnlyViewModel και αντίστροφα. Κάθε πελάτης είναι απομονωμένος από λειτουργικότητα που δεν χρησιμοποιεί και δεν απαιτεί αλλαγές κατά τη βελτίωση άλλων μερών του συστήματος.

ISP και SRP — φυσικό ζεύγος. Το SRP καθορίζει ότι μια κλάση πρέπει να έχει έναν λόγο για αλλαγή. Το ISP εφαρμόζει την ίδια λογική σε διεπαφές: μια διεπαφή πρέπει να εξυπηρετεί ένα σενάριο πελάτη. Μια κλάση μπορεί να υλοποιεί πολλές στενές διεπαφές (κάθε μία αντιστοιχεί σε μία ευθύνη), που είναι πιο καθαρό από μία παχιά διεπαφή με πολλαπλές ευθύνες.

ISP και OCP σχετίζονται επίσης: οι στενές διεπαφές επεκτείνονται ευκολότερα. Η προσθήκη μιας νέας μεθόδου σε μια στενή διεπαφή επηρεάζει μόνο τους πελάτες της. Η προσθήκη μεθόδου σε μια παχιά διεπαφή επηρεάζει όλους τους πελάτες — δυνητικά παραβιάζοντας το OCP, εάν οι πελάτες αναγκάζονται να αλλάξουν την υλοποίησή τους.

ISP και DIP λειτουργούν μαζί: το DIP απαιτεί εξάρτηση από αφαιρέσεις. Το ISP καθιστά αυτές τις αφαιρέσεις στενές και εστιασμένες. Η εξάρτηση από μια ευρεία διεπαφή είναι ακόμα εξάρτηση από αφαίρεση, αλλά “κακή” αφαίρεση από την άποψη του ISP. Τέσσερις αρχές (SRP, OCP, ISP, DIP) σχηματίζουν την “πυραμίδα αρθρωτότητας”: οι SRP και ISP καθορίζουν όρια, οι OCP και DIP — τρόπους επέκτασης και σύνδεσης.

Εφαρμογή του ISP σε αρχιτεκτονική component

Αρχιτεκτονική component σε κινητά έργα (modules, features, layers) επωφελείται από το ISP σε επίπεδο δημόσιων API. Κάθε module εξάγει στενές διεπαφές για τους καταναλωτές του, όχι μία κοινή πρόσοψη. Αυτό επιτρέπει την αλλαγή της εσωτερικής υλοποίησης του module χωρίς να επηρεάζονται οι καταναλωτές που χρησιμοποιούν μόνο μέρος της λειτουργικότητάς του.

Σε έργα Android με Clean Architecture, το ISP εφαρμόζεται στο UseCase: κάθε UseCase είναι μια ξεχωριστή διεπαφή με μία μέθοδο invoke ή execute. Ο πελάτης (ViewModel) εξαρτάται μόνο από το UseCase που χρειάζεται, όχι από ολόκληρο το repository. Αυτό καθιστά τις εξαρτήσεις διαφανείς και ελέγξιμες.

Συχνές Ερωτήσεις

Το ISP οδηγεί σε υπερβολικό αριθμό διεπαφών;

Ναι, υπερβολική διάσπαση είναι πιθανή. Το ISP δεν απαιτεί μία διεπαφή ανά μέθοδο. Κριτήριο: υπάρχει πελάτης που χρειάζεται μόνο μέρος των μεθόδων της διεπαφής; Εάν όλοι οι πελάτες χρησιμοποιούν όλες τις μεθόδους — η διεπαφή δεν χρειάζεται διαχωρισμό. Το βέλτιστο επίπεδο διάσπασης καθορίζεται από πραγματικά σενάρια χρήσης.

Πώς εφαρμόζεται το ISP σε παραμέτρους συναρτήσεων;

ISP σε επίπεδο παραμέτρων σημαίνει: μια συνάρτηση δεν πρέπει να λαμβάνει αντικείμενα με μεγάλο αριθμό πεδίων εάν χρησιμοποιεί μόνο μέρος από αυτά. Αντίθετα, θα πρέπει να μεταδίδονται μόνο τα απαραίτητα δεδομένα ή να χρησιμοποιούνται εξειδικευμένες διεπαφές (για παράδειγμα, η διεπαφή Renderable αντί για πλήρες User).

Σε τι διαφέρει το ISP από το LSP;

LSP αφορά τη σωστή κληρονομικότητα και συμπεριφορική συμβατότητα υποτύπων. ISP αφορά τον σχεδιασμό διεπαφών: οι πελάτες δεν πρέπει να εξαρτώνται από μεθόδους που δεν χρησιμοποιούν. Το LSP απαντά στην ερώτηση “μπορεί μια υποκλάση να χρησιμοποιηθεί αντί της βασικής κλάσης;”, το ISP — “χρειάζεται ο πελάτης ολόκληρη τη διεπαφή;”.

Πώς απλοποιεί το ISP τη δοκιμή;

Οι στενές διεπαφές απλοποιούν τη δημιουργία mock αντικειμένων: η δοκιμή δημιουργεί ένα mock με μία ή δύο μεθόδους, όχι με δέκα. Όσο λιγότερες μέθοδοι υπάρχουν σε μια διεπαφή, τόσο πιο εύκολο είναι να προσομοιωθεί η συμπεριφορά της. Αυτό μειώνει το γνωστικό φορτίο του προγραμματιστή δοκιμής και μειώνει την πιθανότητα σφαλμάτων στη λογική mock.

Πότε μπορεί κανείς να παρεκκλίνει από το ISP;

Εάν η διεπαφή είναι σταθερή και όλοι οι πελάτες χρησιμοποιούν όλες τις μεθόδους — η διάσπαση είναι περιττή. Τυπικό παράδειγμα: πρωτόκολλα UIKit που σχεδίασε η Apple. Ο διαχωρισμός τους είναι επικίνδυνος, καθώς το UIKit αναμένει πλήρη υλοποίηση του εκπροσώπου. Σε τέτοιες περιπτώσεις, η παραβίαση του ISP δικαιολογείται από τη σταθερότητα του API.

Σύνοψη

  • ISP (Interface Segregation Principle) — αρχή διαχωρισμού διεπαφών, τέταρτη στο SOLID
  • Ο πελάτης δεν πρέπει να εξαρτάται από μεθόδους που δεν χρησιμοποιεί
  • Οι παχιές διεπαφές αναγκάζουν κλάσεις να υλοποιούν περιττές μεθόδους ως κενές ή με εξαιρέσεις
  • Ο διαχωρισμός διεπαφών μειώνει τη σύζευξη και απομονώνει πελάτες από αλλαγές
  • ISP + SRP σχηματίζουν όρια modules: μία ευθύνη — ένα στενό συμβόλαιο
  • Η δοκιμή mock απλοποιείται: η στενή διεπαφή απαιτεί λιγότερη προσομοίωση
  • Η βέλτιστη διάσπαση καθορίζεται από πραγματικά σενάρια πελατών, όχι από μέγιστη διάσπαση

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης