一、创建型设计模式
关乎对象创建方式的设计模式是“创建型设计模式”(creational design patern)。一般我们都是通过调用构造器(也就是用参数来调用类对象)来创建对象的,但有时候需要以更灵活的方式来创建对象,而这正式创建型设计模式的用途。
对于python程序员来说,其中某些设计模式彼此之间非常相似,而另外一些则根本用不到。而有些设计模式主要是为c++这种语言设计的,目的是绕开这些编程语言种的某些限制。而python语言没有这些限制,所以用不到。
1.1 抽像工厂模式
“抽像工厂模式”(Abstract Factory Pattern)用来创建复杂的对象,这种对象由许多个小对象组成,而这些小对象都属于某个特定的“系列”(family)。
比方说,在GUI系统里可以设计“抽像控件工厂”(abstract widget factory),并设计三个“具体子类工厂”(concrete subclass factory): MacWidgetFactory、XfceWidgetFactory、WindowsWidgetFactory,它们都提供创建一种对象的方法(例如都提供创建按钮的make_button()方法,都是提供创建数值调整框的make_spinbox()方法),而具体创建出来的对象的风格则与 *** 作系统平台相符。我们可以编写create_dialog()函数,令其以“工厂实例”(factory instance)为参数来创建OS X,Xfce以及Windows风格的对话框,对话框的具体风格取决于传进来的工厂参数。
1) 经典的抽像工厂模式
1.1 抽像工厂的使用方式
import os import sys import tempfile def main(): if len(sys.argv) > 1 and sys.argv[1] == "-P": # For regression testing create_diagram(DiagramFactory()).save(sys.stdout) create_diagram(SvgDiagramFactory()).save(sys.stdout) return textFilename = os.path.join(tempfile.gettempdir(), "diagram.txt") svgFilename = os.path.join(tempfile.gettempdir(), "diagram.svg") txtDiagram = create_diagram(DiagramFactory()) txtDiagram.save(textFilename) print("wrote", textFilename) svgDiagram = create_diagram(SvgDiagramFactory()) svgDiagram.save(svgFilename) print("wrote", svgFilename)
1.2 生成对象的函数
def create_diagram(factory): diagram = factory.make_diagram(30, 7) rectangle = factory.make_rectangle(4, 1, 22, 5, "yellow") text = factory.make_text(7, 3, "Abstract Factory") diagram.add(rectangle) diagram.add(text) return diagram
1.3 抽像类工厂
class DiagramFactory: def make_diagram(self, width, height): return Diagram(width, height) def make_rectangle(self, x, y, width, height, fill="white", stroke="black"): return Rectangle(x, y, width, height, fill, stroke) def make_text(self, x, y, text, fontsize=12): return Text(x, y, text, fontsize)
1.4 具体工厂类
class SvgDiagramFactory(DiagramFactory): def make_diagram(self, width, height): return SvgDiagram(width, height) def make_rectangle(self, x, y, width, height, fill="white", stroke="black"): return SvgRectangle(x, y, width, height, fill, stroke) def make_text(self, x, y, text, fontsize=12): return SvgText(x, y, text, fontsize)
1.5 控制类
BLANK = " " CORNER = "+" HORIZonTAL = "-" VERTICAL = "|" class Diagram: def __init__(self, width, height): self.width = width self.height = height self.diagram = _create_rectangle(self.width, self.height, BLANK) def add(self, component): for y, row in enumerate(component.rows): for x, char in enumerate(row): self.diagram[y + component.y][x + component.x] = char def save(self, filenameOrFile): file = None if isinstance(filenameOrFile, str) else filenameOrFile try: if file is None: file = open(filenameOrFile, "w", encoding="utf-8") for row in self.diagram: print("".join(row), file=file) finally: if isinstance(filenameOrFile, str) and file is not None: file.close()
1.6
def _create_rectangle(width, height, fill): rows = [[fill for _ in range(width)] for _ in range(height)] for x in range(1, width - 1): rows[0][x] = HORIZonTAL rows[height - 1][x] = HORIZonTAL for y in range(1, height - 1): rows[y][0] = VERTICAL rows[y][width - 1] = VERTICAL for y, x in ((0, 0), (0, width - 1), (height - 1, 0), (height - 1, width -1)): rows[y][x] = CORNER return rows
1.7
class Rectangle: def __init__(self, x, y, width, height, fill, stroke): self.x = x self.y = y self.rows = _create_rectangle(width, height, BLANK if fill == "white" else "%")
1.8
class Text: def __init__(self, x, y, text, fontsize): self.x = x self.y = y self.rows = [list(text)]
1.9
SVG_START = """ n" SVG_RECTANGLE = """""" SVG_TEXT = """ {text} """ SVG_SCALE = 20 class SvgDiagram: def __init__(self, width, height): pxwidth = width * SVG_SCALE pxheight = height * SVG_SCALE self.diagram = [SVG_START.format(**locals())] outline = SvgRectangle(0, 0, width, height, "lightgreen", "black") self.diagram.append(outline.svg) def add(self, component): self.diagram.append(component.svg) def save(self, filenameOrFile): file = None if isinstance(filenameOrFile, str) else filenameOrFile try: if file is None: file = open(filenameOrFile, "w", encoding="utf-8") file.write("n".join(self.diagram)) file.write("n" + SVG_END) finally: if isinstance(filenameOrFile, str) and file is not None: file.close()
1.10
class SvgRectangle: def __init__(self, x, y, width, height, fill, stroke): x *= SVG_SCALE y *= SVG_SCALE width *= SVG_SCALE height *= SVG_SCALE self.svg = SVG_RECTANGLE.format(**locals()) class SvgText: def __init__(self, x, y, text, fontsize): x *= SVG_SCALE y *= SVG_SCALE fontsize *= SVG_SCALE // 10 self.svg = SVG_TEXT.format(**locals())
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)