Skip to content

Latest commit

 

History

History
101 lines (67 loc) · 6.59 KB

Flyweight.md

File metadata and controls

101 lines (67 loc) · 6.59 KB

ПАТТЕРНЫ ПРОЕКТИРОВАНИЯ


Авторы:

Ямалиева Карина Радисовна
Шайхуллина Диля Марсельевна

Паттерн легкове (Flyweight) или "Приспособленец"


Легковеc — это структурный паттерн, который экономит память, благодаря разделению общего состояния, вынесенного в один объект, между множеством объектов. Легковес позволяет экономить память, кешируя одинаковые данные, используемые в разных объектах.


Проблема

На досуге вы решили написать небольшую игру, в которой игроки перемещаются по карте и стреляют друг в друга. Фишкой игры должна была стать реалистичная система частиц. Пули, снаряды, осколки от взрывов – всё это должно красиво летать и радовать взгляд.

Игра отлично работала на вашем мощном компьютере. Однако ваш друг сообщил, что игра начинает тормозить и вылетает через несколько минут после запуска. Покопавшись в логах, вы обнаружили, что игра вылетает из-за недостатка оперативной памяти. У вашего друга компьютер значительно менее «прокачанный», поэтому проблема у него и проявляется так быстро.

И действительно, каждая частица представлена собственным объектом, имеющим множество данных. В определённый момент, когда побоище на экране достигает кульминации, новые объекты частиц уже не вмещаются в оперативную память компьютера, и программа вылетает.


Решение

Если внимательно посмотреть на класс частиц, то можно заметить, что цвет и спрайт занимают больше всего памяти. Более того, они хранятся в каждом объекте, хотя фактически их значения одинаковы для большинства частиц.

Остальное состояние объектов – координаты, вектор движения и скорость – отличаются для всех частиц. Таким образом, эти поля можно рассматривать как контекст, в котором частица используется. А цвет и спрайт – это данные, не изменяющиеся во времени.

Неизменяемые данные объекта принято называть «внутренним состоянием». Все остальные данные – это «внешнее состояние».

Паттерн Легковес предлагает не хранить в классе внешнее состояние, а передавать его в те или иные методы через параметры. Таким образом, одни и те же объекты можно будет повторно использовать в различных контекстах. Но главное – понадобится гораздо меньше объектов, ведь теперь они будут отличаться только внутренним состоянием, а оно имеет не так много вариаций.
В нашем примере с частицами достаточно будет оставить всего три объекта с отличающимися спрайтами и цветом – для пуль, снарядов и осколков. Несложно догадаться, что такие облегчённые объекты называют легковéсами .


Пример:


  """Separate class for Complex Cars"""

  def __init__(self):

      pass

  def cars(self, car_name):

      return "ComplexPattern[% s]" % (car_name)


class CarFamilies(object):

  """dictionary to store ids of the car"""

  car_family = {}

  def __new__(cls, name, car_family_id):
      try:
          id = cls.car_family[car_family_id]
      except KeyError:
          id = object.__new__(cls)
          cls.car_family[car_family_id] = id
      return id

  def set_car_info(self, car_info):

      """set the car information"""

      cg = ComplexCars()
      self.car_info = cg.cars(car_info)

  def get_car_info(self):

      """return the car information"""

      return (self.car_info)



if __name__ == '__main__':
  car_data = (('a', 1, 'Audi'), ('a', 2, 'Ferrari'), ('b', 1, 'Audi'))
  car_family_objects = []
  for i in car_data:
      obj = CarFamilies(i[0], i[1])
      obj.set_car_info(i[2])
      car_family_objects.append(obj)

  """similar id's says that they are same objects """

  for i in car_family_objects:
      print("id = " + str(id(i)))
      print(i.get_car_info())

Преимущества и недостатки

Преимущества

  • Экономит оперативную память.

Недостатки

  • Расходует процессорное время на поиск/вычисление контекста.
  • Усложняет код программы из-за введения множества дополнительных классов.