创建型模式:建造者模式(Builder)

意图:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

结构:
builder

示例:
builder_example

Builder(TextConverter):为创建产品对象的各个部件提供抽象接口。

class TextConverter(ABC):

    @abstractmethod
    def convert_character(self, char):
        """转换普通文本"""

    @abstractmethod
    def convert_font_change(self, font):
        """转换RTF控制字"""

    @abstractmethod
    def convert_paragraph(self):
        """转换RTF标记"""

ConcreteBuilder(ASCIIConverter、TeXConverter、TextWidgetConverter):实现Builder接口来构造或装配产品的各个部件,提供一个检索产品的接口(返回产品对象)。

class ASCIIConverter(TextConverter):

    def __init__(self):
        self.__ascii_text = ASCIIText()

    def convert_character(self, char):
        converted_char = ascii(char)
        print('convert character(%s) with ascii' % converted_char)
        self.__ascii_text.char.append(converted_char)

    def convert_font_change(self, font):
        raise AttributeError('ascii converter cant convert font change')

    def convert_paragraph(self):
        raise AttributeError('ascii converter cant convert paragraph')

    def get_ascii_text(self):
        """返回ascii编码文本"""
        return self.__ascii_text


class TeXConverter(TextConverter):

    def __init__(self):
        self.__tex_text = TeXText()

    def convert_character(self, char):
        converted_char = char.upper()
        print('convert character(%s) with TeX' % converted_char)
        self.__tex_text.char.append(converted_char)

    def convert_font_change(self, font):
        converted_font = font.upper()
        print('convert font_change(%s) with TeX' % converted_font)
        self.__tex_text.font.append(converted_font)

    def convert_paragraph(self):
        print('convert paragraph with TeX')
        self.__tex_text.para.append('para')

    def get_tex_text(self):
        """返回tex风格文本"""
        return self.__tex_text


class TextWidgetConverter(TextConverter):

    def __init__(self):
        self.__text_widget = TextWidget()

    def convert_character(self, char):
        print('convert character(%s) with TextWidget' % char)
        self.__text_widget.char.append(char)

    def convert_font_change(self, font):
        print('convert font_change(%s) with TextWidget' % font)
        self.__text_widget.font.append(font)

    def convert_paragraph(self):
        print('convert paragraph with TextWidget')
        self.__text_widget.para.append('para')

    def get_text_widget(self):
        """返回文本组件"""
        return self.__text_widget

Director(RTFReader):构造一个使用Builder接口的对象,提供了construct建造方法,该方法中应该调用Builder中的创建各部件的接口(此时实际装配了一个完整的产品)。

class RTFReader:

    def __init__(self, builder: TextConverter):
        self.builder = builder

    def parse_RTF(self, rtf_list):
        """construct()建造方法"""
        for rtf in rtf_list:
            if rtf.sign == 'CHAR':
                self.builder.convert_character(rtf.char)
            elif rtf.sign == 'FONT':
                self.builder.convert_font_change(rtf.font)
            elif rtf.sign == 'PARA':
                self.builder.convert_paragraph()

Product(ASCIIText、TeXText、TextWidget):表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程。

class ASCIIText:

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

    def show(self):
        print('ascii text: %s' % ''.join(self.char))


class TeXText:

    def __init__(self):
        self.char = []
        self.font = []
        self.para = []

    def show(self):
        print('TeX char: %s' % ''.join(self.char))
        print('TeX font: %s' % ''.join(self.font))
        print('TeX para: %s' % ''.join(self.para))


class TextWidget:

    def __init__(self, window='PC_WINDOW'):
        self.window = window
        self.char = []
        self.font = []
        self.para = []

    def show(self):
        print('show text: %s in %s' % (''.join(self.char), self.window))
        print('show text: %s in %s' % (''.join(self.font), self.window))
        print('show text: %s in %s' % (''.join(self.para), self.window))

Client:利用所需的Builder创建Director对象,利用建造方法construct(),构建产品的各个部件,最后从Builder中获取完整的产品。

交互图:
builder_example2

分析:

  1. Builder提供给Directror构造产品的抽象接口,该接口隐藏了产品的表示和内部结构,以及产品是如何装配的。当改变产品的内部结构时,只需要重新定义一个ConcreteBuilder,并改变其内部的部件装备的结构(如将TeX风格的普通文本改为str.lower()时,只要重新定义ConcreteBuilder,并修改部件的装配方法)。
  2. 对产品的构造过程进行更精细的控制。产品是在导向者Director的控制下,一步一步的构造完成的,且仅当各个部件构造结束成为完整的产品时才从Builder中取回该产品。
  3. Builder着重于一步一步构造一个复杂对象,且在最后一步构造完成时返回。而Abstract Factory着重于多个系列同个产品族的产品对象,且该对象是立刻返回的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值