Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Python: Общие вопросы > Помогите с шаблоном проектирования


Автор: Angela 8.9.2006, 19:16
Может кто знает как реализовать (или где найти уже готовый код)  на Питоне шаблон проектирования Prototype (Прототип) ? smile 
 Заране спасибо

Автор: Artemios 8.9.2006, 21:32
Цитата(Angela @ 8.9.2006,  19:16)
Может кто знает как реализовать (или где найти уже готовый код)  на Питоне шаблон проектирования Prototype (Прототип) (можно конечно и другой шаблон)? smile 
 Заране спасибо

А ты случайно не в Саратовском гос.университете учишся? smile

Добавлено @ 21:47 
Цитата(Angela @  8.9.2006,  19:16 Найти цитируемый пост)
можно конечно и другой шаблон

Шаблон Observer (наблюдатель), точнее его реализация на примере различных отображений субъекта Число:
Код

#! /usr/bin/env python
# -*- coding: cp1251 -*-

"""
пример паттерна - Наблюдатель
Определяет зависимость типа один ко многим между объектами таким образом,
что при изменении состояния одного объекта все зависящие от него
оповещаются об этом и автоматически обновляются.
"""

class Subject:
  """
  Субъект:
    - располагает информацией о своих наблюдателях.
      За субъектом может "следить" любое число наблюдателей;
    - предоставляет интерфейс для присоединения и отделения наблюдателей;
  """
  def __init__(self):
    self.observerLst = []

  def attach(self, observer):
    """
    Присоединяет наблюдателя observer к субъекту
    """
    assert observer not in self.observerLst
    assert not hasattr(observer, 'subject')
    observer.subject = self
    self.observerLst.append(observer)
    observer.update()

  def detach(self, observer):
    """
    Отделяет наблюдателя observer от субъекта
    """
    assert observer in self.observerLst
    assert hasattr(observer, 'subject')
    del observer.subject
    self.observerLst.remove(observer)
    observer.update()

  def notify(self):
    """
    Синхронизирует состояние субъекта и его наблюдателей
    """
    for observer in self.observerLst:
      observer.update()

class Observer:
  """
  Наблюдатель:
    - определяет интерфейс обновления для объектов,
      которые должны быть уведомлены об изменении субъекта;
  """
  def __del__(self):
    """
    Перед удалением наблюдателя отделяет его субъекта subject
    """
    if hasattr(self, 'subject'):
      self.subject.detach(self)

  def update(self):
    """
    Синхронизирует состояние наблюдателя и субъекта
    """
    assert False


class Number(Subject):
  """
  Субъект:
    - хранит число number
  """
  def __init__(self, number):
    Subject.__init__(self)
    self.number = number

  def setNumber(self, number):
    """
    Устанавливает новое значение числа number
    """
    self.number = number
    self.notify()


class Decimal(Observer):
  """
  Наблюдатель:
    - хранит число субъекта number в десятичном представлении
  """
  def __init__(self):
    self.decimal = ""

  def update(self):
    if hasattr(self, 'subject'):
      self.decimal = "%d" % self.subject.number
    else:
      self.decimal = ""
    print self, "decimal =", self.decimal

class Octal(Observer):
  """
  Наблюдатель:
    - хранит число субъекта number в восьмеричном представлении
  """
  def __init__(self):
    self.octal = ""

  def update(self):
    if hasattr(self, 'subject'):
      self.octal = "%o" % self.subject.number
    else:
      self.octal = ""
    print self, "octal =", self.octal

class Hexadecimal(Observer):
  """
  Наблюдатель:
    - хранит число субъекта number в шестнадцатиричном представлении
  """
  def __init__(self):
    self.hexadecimal = ""

  def update(self):
    if hasattr(self, 'subject'):
      self.hexadecimal = "%x" % self.subject.number
    else:
      self.hexadecimal = ""
    print self, "hexadecimal =", self.hexadecimal

if __name__ == "__main__":
  number = Number(12345)

  decimal1 = Decimal()
  number.attach(decimal1)

  decimal2 = Decimal()
  number.attach(decimal2)

  number.setNumber(54321)

  number.detach(decimal1)

  octal1 = Octal()
  number.attach(octal1)

  hexadecimal1 = Hexadecimal()
  number.attach(hexadecimal1)
  for observer in number.observerLst:
      print "observer ", observer

  number.setNumber(12543)
  number.detach(hexadecimal1)
  del decimal2
  number.setNumber(55555)


Шаблон Composite (Компоновщик):

Код

#! /usr/bin/env python
# -*- coding: cp1251 -*-

"""
пример паттерна  - Компоновщик
Компонует объекты в древовидные структуры для представления иерархии часть-целое.
Позволяет клиентам единообразно трактовать индивидуальные и составные объекты.
"""

class File:
  """
  Компонент:
    - объявляет интерфейс для компонуемых объектов;
    - предоставляет подходящую реализацию операций по умолчанию,
      общую для всех классов;
  """
  def __init__(self, size):
    self.size = size

  def isDir(self):
    return isinstance(self, Dir)

  def getName(self):
    assert hasattr(self, 'name')
    return self.name

  def getSize(self):
    return self.size

  def ls(self):
    return [self.name]

  def __hash__(self):
    assert hasattr(self, 'name')
    return hash(self.name)

class Dir(File):
  """
  Составной объект:
    - определяет поведение компонентов, у которых есть потомки;
    - хранит компоненты-потомки;
    - реализует относящиеся к управлению потомками операции в интерфейсе класса Компонент;
  """
  def __init__(self):
    self.name = "/"
    self.containerDct = {}

  def getSize(self):
    size = 0
    for file in self.containerDct.itervalues():
      size += file.getSize()
    return size

  def ls(self):
    lst = [self.name]
    for file in self.containerDct.itervalues():
      lst.extend(map(lambda x: self.name + x, file.ls()))
    return lst

  def __len__(self):
    return len(self.containerDct)

  def __getitem__(self, name):
    return self.containerDct[name]

  def __setitem__(self,name, file):
    if file.isDir():
      file.name = name + '/'
    else:
      file.name = name
    self.containerDct[name] = file

  def __delitem__(self, name):
    del self.containerDct[name]

  def __contains__(self, name):
    return name in self.containerDct

  def __iter__(self):
    return self.containerDct.itervalues()

if __name__ == "__main__":
  f1 = File(12)
  d1 = Dir()
  d1["f1"] = f1
  d2 = Dir()
  d2["d1"] = d1
  f2 = File(21)
  d1["f2"] = f2
  print f1.getSize()
  print f2.ls()
  print d2.getSize()
  print d2.ls()
  del d1["f2"]
  print d2.ls()


smile

Автор: Angela 8.9.2006, 22:39
Учусь там. Но если ты тоже оттуда ( я об этом даже и не подумала), тогда знаешь, что эти примеры задают для разбора. Но все равно спасибо. 
А ты случайно не делал это задание?

Автор: Cr@$h 8.9.2006, 23:42

M
Cr@$h
Приветствую Angela, нового участника форума Python Vingrad! :)

Автор: Artemios 9.9.2006, 18:15
Цитата(Angela @  8.9.2006,  22:39 Найти цитируемый пост)
тогда знаешь, что эти примеры задают для разбора.

Я даже знаю, кто их написал ;) 

Цитата(Angela @  8.9.2006,  22:39 Найти цитируемый пост)
А ты случайно не делал это задание?

Я случайно его задал ;) Или мой коллега...
Догадалась? ;)

Автор: Cr@$h 11.9.2006, 18:06

M
Cr@$h
Из этой темы выделилось интересное обсуждение Преподавание Python в ВУЗах.

Автор: Artemios 12.9.2006, 08:55
Angela, сама понимаешь, программу за тебя написать не могу, но если есть вопросы, или что-то непонятно - не стесняйся - обращайся, спрашивай, проси помочь. Я для того к вам на паре и "приставлен" smile  А.В.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)