Πώς μπορεί η χρήση του μοτίβου Singleton να παραβιάζει τις αρχές του πολυμορφισμού;
sobes.tech AI
Απάντηση από AI
Το Singleton περιορίζει τη δημιουργία αντικειμένων μιας κλάσης σε ένα μόνο αντικείμενο. Ο πολυμορφισμός, από την άλλη πλευρά, υπονοεί τη δυνατότητα εργασίας με αντικείμενα διαφορετικών κλάσεων μέσω μιας κοινής διεπαφής ή βασικής κλάσης.
Η παραβίαση συμβαίνει όταν ο κώδικας πελάτη είναι αυστηρά δεμένος σε μια συγκεκριμένη κλάση Singleton, αντί να εργάζεται με μια αφαιρετική (πρωτόκολλο ή βασική κλάση). Σε αυτήν την περίπτωση, δεν είναι δυνατή η αντικατάσταση με ένα άλλο εναλλακτικό αντικείμενο που υλοποιεί την ίδια λειτουργικότητα, καθώς ο πελάτης αναμένει ακριβώς ένα αντίγραφο Singleton.
// Κακή χρήση - ο πελάτης εξαρτάται άμεσα από το ConcreteSingleton
class ConcreteSingleton {
static let shared = ConcreteSingleton()
private init() {}
func performAction() {
print("Εκτέλεση ενέργειας από το ConcreteSingleton")
}
}
// Πελάτης
func clientFunction() {
// Στερεά σύνδεση με το ConcreteSingleton
ConcreteSingleton.shared.performAction()
}
// Καλή χρήση - ο πελάτης εξαρτάται από ένα πρωτόκολλο
protocol Service {
func performAction()
}
class RealService: Service {
func performAction() {
print("Εκτέλεση ενέργειας από το RealService")
}
}
class MockService: Service {
func performAction() {
print("Εκτέλεση ενέργειας από το MockService")
}
}
// Singleton για παροχή υλοποιήσεων μέσω πρωτοκόλλου (προαιρετικά, μπορεί να χρησιμοποιηθεί DI)
class ServiceProvider {
static let shared = ServiceProvider()
private init() {}
private var currentService: Service = RealService()
func setService(_ service: Service) {
currentService = service
}
func getService() -> Service {
return currentService
}
}
// Πελάτης
func flexibleClientFunction() {
// Εργασία μέσω αφαιρετικότητας (πρωτόκολλο)
let service = ServiceProvider.shared.getService()
service.performAction()
}
// Παραδείγματα πολυμορφισμού με ευέλικτο πελάτη
// ServiceProvider.shared.setService(MockService())
// flexibleClientFunction() θα χρησιμοποιεί το MockService
Έτσι, η άμεση χρήση της στατικής ιδιότητας shared του Singleton στον κώδικα πελάτη μειώνει την ευελιξία και δυσκολεύει την αντικατάσταση υλοποιήσεων, κάτι που αποτελεί βασικό στοιχείο του πολυμορφισμού όταν εργάζεστε με διαφορετικούς τύπους αντικειμένων μέσω μιας κοινής διεπαφής. Η λύση είναι να εργάζεστε με το στιγμιότυπο του Singleton μέσω πρωτοκόλλου ή βασικής κλάσης.