具有许多依赖组件的系统模式中的循环依赖关系



需要以下模式:

  1. 计算机具有物理组件(硬盘驱动器,屏幕,扬声器(
  2. 您可以在其上安装应用程序(这是计算机所知道的有关应用程序的所有信息(
  3. 没有计算机的应用程序将无法运行,必须安装它们
  4. 应用可以使用计算机的物理组件

由于计算机包含应用程序并且应用程序需要访问计算机,因此存在循环依赖关系。这是使用它的合适情况,还是有更好的模式来解决此类问题?

示例代码:

class Screen:
def display(self, image):
print('Displaying "{}"'.format(image))

class Speaker:
def play(self, sound):
print('Playing "{}"'.format(sound))

class HardDrive:
def write(self, data):
print('Writing "{}" to disk'.format(data))

class Applications(dict):
def __setitem__(self, name, app):
try:
self.__getitem__(name)
raise PermissionError('App "{name}" is already installed!'.format(name=name))
except KeyError:
super(Applications, self).__setitem__(name, app)

class Computer:
def __init__(self):
self.screen = Screen()
self.speaker = Speaker()
self.disk = HardDrive()
self.apps = Applications()
def install_app(self, factory, *args, **kwargs):
app = factory(self, *args, **kwargs)
self.apps[app.name] = app
def __getattr__(self, item):
try:
return self.apps[item]
except KeyError:
pass

class App(object):
def __init__(self, computer, name=None):
self.computer = computer
self.name = name

class PdfReader(App):
def __init__(self, computer, name='pdf_reader'):
super(PdfReader, self).__init__(computer, name)
self.computer.disk.write('pdf reader data')
def read_document(self, document):
self.computer.screen.display(document)

class VideoPlayer(App):
def __init__(self, computer, name='video_player'):
super(VideoPlayer, self).__init__(computer, name)
self.computer.disk.write('pdf reader data')
def play_video(self, video):
self.computer.screen.display(video)
self.computer.speaker.play(video)

if __name__ == '__main__':
home_pc = Computer()
home_pc.install_app(PdfReader)
home_pc.install_app(VideoPlayer)
home_pc.pdf_reader.read_document('Harry_Potter.pdf')
home_pc.video_player.play_video('Pulp_Fiction.mp4')

为什么是循环的?为什么(失踪的(installer

class Computer:
# no change: def __init__(self):
def install_app(self, installer, *args, **kwargs):
try:
app = installer(self, *args, **kwargs)               # def installer() missing
self.apps[app.name] = app  # install if it worked    # but I assume it does smth
except InstallError ex:
# do something if installer throws InstallError
pass

如果安装过程不起作用,请引发安装错误。如果有效,只需将应用程序添加到计算机即可。不涉及循环。

顺便说一句。我的笔记本电脑上有大约 2-4 个视频播放器软件(Real Player、vlc 等( - 如果您允许在实例化应用程序时提供应用程序的"名称"以允许多个 VideoPlayer-App,您将获得更灵活。

最新更新