文章

设计模式-生成器模式

应用场景

To separate the construction of an object from its representation.

顾名思义, 将对象的结构与呈现形式进行分离.

经常会有将数据或对象从一种结果导出为其他呈现形式的需求, 比如PPT转PDF, 表格转图表等等.

classDiagram
    direction LR
    class Presentation{
        + export()
    }

    class PresentationBuilder{
        <<interface>>
        + addSlide()
    }

    class PDFDocumentBuilder{
        + addSlide()
        + getPDFDocument()
    }

    class MovieBuilder{
        + addSlide()
        + getMovie()
    }

    Presentation *--> PresentationBuilder
    PresentationBuilder <|-- PDFDocumentBuilder
    PresentationBuilder <|-- MovieBuilder

简单的python实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
class Slide:

    def __init__(self, text):
        self.text = text


class PresentationBuilder(ABC):

    @abstractmethod
    def add_slide(self, slide: Slide):
        pass

    @abstractmethod
    def get_result(self):
        pass


class PDFBuilder(PresentationBuilder):

    def __init__(self):
        self.document = []

    def add_slide(self, slide: Slide):
        self.document.append(slide)

    def get_result(self):
        return self.document


class MovieBuilder(PresentationBuilder):

    def __init__(self):
        self.frames = []
        self.duration = []

    def add_slide(self, slide: Slide):
        self.frames.append(slide)
        self.duration.append(randint(1, 3))

    def get_result(self):
        return list(zip(self.frames, self.duration))


class Presentation:

    def __init__(self, *slides: Slide):
        self.slides = slides or []

    def add_slide(self, slide: Slide):
        self.slides.append(slide)

    def remove_slide(self, index: int):
        self.slides.remove(index)

    def export(self, builder: PresentationBuilder):

        for slide in self.slides:
            builder.add_slide(slide)


if __name__ == "__main__":

    s = [f"slide {i}" for i in range(3)]
    p = Presentation(*s)
    pdf = PDFBuilder()
    movie = MovieBuilder()
    p.export(pdf)
    p.export(movie)
    print(pdf.get_result())
    print(movie.get_result())

输出结果:

1
2
['slide 0', 'slide 1', 'slide 2']
[('slide 0', 2), ('slide 1', 1), ('slide 2', 1)]
本文由作者按照 CC BY 4.0 进行授权