Альтернативное описание паттернов проектирования: abstractfactory

в 4:18, , рубрики: python, образование, паттерны проектирования, метки: , ,

Продолжение топика Альтернативное описание паттернов проектирования

Abstract factory — предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов, не специфицируя их конкретных классов.

На нашем, осмысленном примере это означает, класс FileSystemAbstract представляет собой интерфейс для создания головной папки, папок, файлов и ссылок. В результате это позволяет изменять поведение системы порождая от FileSystemAbstract новые классы, например FileSystem.

Для удобства сравнения кода с базовым примером, он слева, добавлена картинка аля — diff.

Изображение - savepic.su — сервис хранения изображений

Сам код примера.

# -*- coding: utf-8 -*-

fileSystem = None

class File:
  def __init__(self, size):
    self.size = size
    self.ind = fileSystem.create(self)
    self.parent = None

  def name(self):
    if not self.parent:
      return ""
    else:
      return self.parent.getName(self.ind)

class Dir:
  def __init__(self):
    self.ind = fileSystem.create(self)
    self.parent = None
    self.container = {}

  def getName(self, ind):
    return self.name() + self.container[ind]

  def name(self):
    if not self.parent:
      return ""
    else:
      return self.parent.getName(self.ind) + "/"

  def size(self):
    return len(self.container)

  def add(self, name, file):
    file.parent = self
    self.container[file.ind] = name

class Root(Dir):
  def __init__(self):
    Dir.__init__(self)

  def name(self):
    return "/"

class Link:
  def __init__(self, link):
    self.link = link
    self.ind = fileSystem.create(self)
    self.parent = None

  def name(self):
    if not self.parent:
      return " -> " + self.link.name()
    else:
      return self.parent.getName(self.ind) + " -> " + self.link.name()

  def size(self):
    return 8

class FileSystemAbstract:
  def __init__(self):
    self.container = {}

  def create(self, file):
    ind = hash(file)
    self.container[ind] = file
    return ind

  def createFile(self, size):
    pass

  def createDir(self):
    pass

  def createRoot(self):
    pass

  def createLink(self, link):
    pass

  def find(self, name):
    for value in self.container.itervalues():
      if value.name() == name:
        return value
    return None

  def printAll(self):
    for value in self.container.itervalues():
      if isinstance(value, File):
        print "file: %8d %s" % (value.size, value.name())
      elif isinstance(value, Dir):
        print " dir: %8d %s" % (value.size(), value.name())
      elif isinstance(value, Link):
        print "link: %8d %s" % (value.size(), value.name())

class FileSystem(FileSystemAbstract):
  def __init__(self):
    FileSystemAbstract.__init__(self)

  def createFile(self, size):
    return File(size)

  def createDir(self):
    return Dir()

  def createRoot(self):
    return Root()

  def createLink(self, link):
    return Link(link)

if __name__ == "__main__":
  fileSystem = FileSystem()
  root = fileSystem.createRoot()
  etc = fileSystem.createDir()
  root.add("etc", etc)
  home = fileSystem.createDir()
  root.add("home", home)
  user = fileSystem.createDir()
  home.add("user", user)
  user.add("readme.txt", fileSystem.createFile(1177))
  user.add(".etc", fileSystem.createLink(etc))
  fileSystem.printAll()
  print "find('/home/user')=", fileSystem.find("/home/user")
  print "find('/home/user/')=", fileSystem.find("/home/user/")

В результате выполнения кода имеем повтор результата базового примера с точностью до перестановки строк:

file:     1177 /home/user/readme.txt
link:        8 /home/user/.etc -> /etc/
 dir:        2 /
 dir:        0 /etc/
 dir:        1 /home/
 dir:        2 /home/user/
find('/home/user')= None
find('/home/user/')= <__main__.Dir instance at 0x7f32ea5b1bd8>

Автор: bya

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js