Форум сайта python.su
ребята, помогите пожалуйста разобраться с паттерном стратегия. я готовлюсь к экзамену и , как мне кажется, изучил вопрос. побудьте преподами и оцените мои знания. возможно, есть пробелы, которые нужно восполнить.
мой ответ будет приблизительно таким:
паттерн стратегия помогает определить поведение объекта в зависимости от его типа. реализуется это через механизм наследования или композиции на этапе создания объекта.
чтобы хорошо понять и запомнить этот паттерн разумно использовать жизненные примеры. далее привожу три таких примера:
1.
например существует программа-игра. она испльзует набор картинок. в зависимости от географического положения пользователя картинки тянутся из БД или сервиса flickr.
перед началом игры при помощи геолокаци определяется местоположение пользователя и на основе этого результата выбирается источник картинок. этот пример иллюстрирует следующий код(геолокацию я опустил, она не иммеет непосредственного отношения к паттерну):class ImageFinder(): def __init__(self, strategy=None): self.action = None if strategy: self.action = strategy() def find(self, image): if(self.action): return self.action.find(image) else: raise UnboundLocalError('no strategyClass!') class ImageFinderFlickr(): def find(self, image): return "Found image in Flickr: " + image class ImageFinderDatabase(): def find(self, image): return "Found image in database: " + image finderBase = ImageFinder() finderFlickr = ImageFinder(strategy=ImageFinderFlickr) finderDatabase = ImageFinder(strategy=ImageFinderDatabase) try: print(finderBase.find('chickens')) except Exception as e: print("exception :", e) print(finderFlickr.find('chickens')) print(finderDatabase.find('dogs'))
2.
пусть существует игра типа ГТА, в кторой есть персонажи, которые пишут ручкой, а есть которые рисуют кистью. на этапе создания этих персонажей каждому в атрибут жётско прописывается стратегия действия. в результате имеем несколько персонажей, поведение которых различается:class People(): tool = None def __init__(self, name): self.name = name def setTool(self, tool): self.tool = tool def write(self, text): self.tool.write(self.name, text) class ToolBase: def write(self, name, text): raise NotImplementedError() class PenTool(ToolBase): def write(self, name, text): print('%s (ручкой) %s' % (name, text)) class BrushTool(ToolBase): def write(self, name, text): print('%s (кистью) %s' % (name, text)) class Student(People): tool = PenTool() class Painter(People): tool = BrushTool() maxim = Student(u'Максим') maxim.write(u'Пишу лекцию о паттерне Стратегия') # Максим (ручкой) Пишу лекцию о паттерне Стратегия sasha = Painter(u'Саша') sasha.write(u'Рисую иллюстрацию к паттерну Стратегия') # Саша (кистью) Рисую иллюстрацию к паттерну Стратегия
3.как думаете, ответ был полный и понятный или есть места, на которые стоит обраттиь внимание и доработать.
допустим, завод выпускает градусники, кторые могут показывать температуру в кельвинах и градусах фаренгейта. после покупки градусник единожды настраивается на нужные единицы, после чего может производить измерение температуры. в этом случае можно систему описать так:from abc import ABC, abstractmethod class Termometer(): def __init__(self, strategy): self.strategy = strategy() def calculate(self): try: print(self.strategy.calculate()) except: print('no straregy error') class Gradus(ABC): @abstractmethod def calculate(self): pass class Farenheit(Gradus): def calculate(self): return 'farenheit value' class Kelvin(Gradus): def calculate(self): return 'kelvin value' class Celsius(Gradus): pass termometer1 = Termometer(Farenheit) termometer1.calculate() termometer2 = Termometer(Kelvin) termometer2.calculate() # error # termometer3 = Termometer(Celsius) # termometer3.calculate()
Отредактировано zlodiak (Март 8, 2019 18:08:40)
Офлайн
zlodiakОй ненене! Стратегия - это инкапсуляция алгоритма, т.е. отделение алгоритма от объекта этот алгоритм использующий.
паттерн стратегия помогает определить поведение объекта в зависимости от его типа. реализуется это через механизм наследования или композиции на этапе создания объекта.
def print_to_file(data): with open("filename") as f: f.write(data) def print_to_console(data): print(data) class Foo: def __init__(self, log_type): self.log_type = log_type def do1(self): if self.log_type == "file": print_to_file("11111") else: print_to_console("11111") def do2(self): if self.log_type == "file": print_to_file("22222") else: print_to_console("2222")
import abc class Logger(metaclass=abc.ABCMeta): @abc.abstractmethod def log(self, data): ... class FileLogger(Logger): def log(self, data): with open("filename") as f: f.write(data) class ConsoleLOgger(Logger): def log(self, data): print(data) class Foo: def __init__(self, logger: Logger): self.logger = logger def do1(self): self.logger.log("11111") def do2(self): self.logger.log("22222") f = Foo(FileLogger()) f.do1() f.do2()
Отредактировано FishHook (Март 8, 2019 18:59:54)
Офлайн