Задний план
Это было несколько лет назад, что я узнал и использовал Дизайн шаблонов во время моей предыдущей работы. Мы разработали программное обеспечение для медицинских роботов в C ++ (I.e OOP) и разные образцы дизайна часто использовались в нашем коде. Позже, когда я начал работать в нашем стартапе, мы много развиваем в Python и HTML5 Для больших данных и веб-проектов, таким образом, мы используем вряд ли узоров дизайна.
Недавно я читаю эту книгу о Дизайн шаблонов как показано ниже:
Эта книга очень интересная, и это заставляет меня вспоминать знания о проектных узорах. Я понимаю, что мне пора проводить упражнения на рисунке дизайна в Питон .
Singleton упражнения
Итак, сегодня я попробовал простой сценарий для реализации Singleton в Python Отказ Я хочу имитировать случай, когда пользователь называет Siri играть музыку.
ИДТИ!
Нет Синглтон Сейс
Определите обычный класс игрока без внедрения Singleton.
import threading import time ## a global album dict containing three music as well as their length album = {"Love Story":10, "Angels":12, "Elle":18} ### a regular MusicPlayer class which contains a thread for simulating music playing ### 普通的播放器类,自带一个播放线程 class musicplayer(): """ a regular MusicPlayer class """ def __init__(self): self.__currentItem = "" self.__musicLength = 0 self.__timer = 0 self.__thread = threading.Thread(target=self.playsound) def play(self): if self.__thread.isAlive(): pass else: self.__thread.start() def updateItem(self, musicfile, length): self.__currentItem = musicfile self.__musicLength = length self.__timer = 0 def playsound(self): while self.__timer <= self.__musicLength: print(" -- playing {} ---- {}.00/{}.00" .format(self.__currentItem, self.__timer, self.__musicLength)) time.sleep(1) self.__timer +=1 print("{} playing thread has ended".format(self.__currentItem))
Теперь определите довольно простой класс Siri, который имеет только одну функцию runcmd
Для инициализации приложения игрока и воспроизведения музыки.
class Siri(): def __init__(self): pass def runCMD(self, cmd): if cmd.startswith("play music"): music = cmd.replace("play music", "").strip() player = musicplayer() player.updateItem(music, album[music]) player.play()
Теперь попробуйте в Главная функция.
if __name__ == "__main__": musicList = list(album.keys()) siri = Siri() siri.runCMD("play music {}".format(musicList[0])) time.sleep(4) siri.runCMD("play music {}".format(musicList[1])) mainTime = 0 while (mainTime < 20): mainTime+=1 time.sleep(1) print("End of simulation")
Выполните код выше, я вижу, что были созданы два музыкальных игрока, и они одновременно играли разные предметы.
Singleton Case.
Теперь я немного обновляю класс музыкального проигрывателя, так что это класс Singleton-Pattern. Этот класс получен из объект Класс, так что мне нужно определить __new __ ()
и __init __ ()
функции для работы конструктора.
class musicplayer(object): """ ### a SINGLETON MusicPlayer class which contains a thread for simulating music playing """ __instance = None __isInstanceDefined = False def __new__(cls): if not cls.__instance: musicplayer.__instance = super().__new__(cls) return cls.__instance def __init__(self): if not musicplayer.__isInstanceDefined: self.__currentItem = "" self.__musicLength = 0 self.__timer = 0 self.__thread = threading.Thread(target=self.playsound) musicplayer.__isInstanceDefined = True else: pass def play(self): if self.__thread.isAlive(): pass else: self.__thread.start() def updateItem(self, musicfile, length): self.__currentItem = musicfile self.__musicLength = length self.__timer = 0 def playsound(self): while self.__timer <= self.__musicLength: print(" -- playing {} ---- {}.00/{}.00" .format(self.__currentItem, self.__timer, self.__musicLength)) time.sleep(1) self.__timer +=1 print("{} playing thread has ended".format(self.__currentItem))
Теперь снова выполните весь файл кода, и он работает. Существует один и только один экземпляр игрока в моделировании даже Siri изменил музыкальный элемент:
Синглтон декоратор
В книге я прочитал, автор ввел очень изящный способ понять Singleton Узор без модификации существующих классов: используя декоратор. Мне очень нравится этот метод.
Этот метод декоратора явный и простой:
def singletonDecorator(cls, *args, **kwargs): """ defines a Singleton decorator """ instance = {} def wrapperSingleton(*args, **kwargs): if cls not in instance: instance[cls] = cls(*args, **kwargs) return instance[cls] return wrapperSingleton
Теперь я поставил весь файл кода здесь. Обратите внимание, что есть @singletonecorator
Декларация выше моего существующего MusicPlayer
класс:
import threading import time album = {"Love Story":10, "Angels":12, "Elle":18} def singletonDecorator(cls, *args, **kwargs): """ defines a Singleton decorator """ instance = {} def wrapperSingleton(*args, **kwargs): if cls not in instance: instance[cls] = cls(*args, **kwargs) return instance[cls] return wrapperSingleton ### a regular MusicPlayer class which contains a thread for simulating music playing ### 普通的播放器类,自带一个播放线程 @singletonDecorator class musicplayer(): """ a regular MusicPlayer class """ def __init__(self): self.__currentItem = "" self.__musicLength = 0 self.__timer = 0 self.__thread = threading.Thread(target=self.playsound) def play(self): if self.__thread.isAlive(): pass else: self.__thread.start() def updateItem(self, musicfile, length): self.__currentItem = musicfile self.__musicLength = length self.__timer = 0 def playsound(self): while self.__timer <= self.__musicLength: print(" -- playing {} ---- {}.00/{}.00" .format(self.__currentItem, self.__timer, self.__musicLength)) time.sleep(1) self.__timer +=1 print("{} playing thread has ended".format(self.__currentItem)) class Siri(): def __init__(self): pass def runCMD(self, cmd): if cmd.startswith("play music"): music = cmd.replace("play music", "").strip() player = musicplayer() player.updateItem(music, album[music]) player.play() if __name__ == "__main__": musicList = list(album.keys()) siri = Siri() siri.runCMD("play music {}".format(musicList[0])) time.sleep(4) siri.runCMD("play music {}".format(musicList[1])) mainTime = 0 while (mainTime < 20): mainTime+=1 time.sleep(1) print("End of simulation")
Этот новый метод дает тот же результат:
Оригинал: “https://dev.to/jemaloqiu/design-pattern-in-python-singleton-5apj”