第三章:中介模式

一、什么是中介模式

故事
李力最近换了一份工作,大城市换工作意味着就要换一个房子。找房子是一个特别繁琐的过程,而且在北京这座城市,你几乎找不到一手房东,因为90%的房源都掌握在房屋中介的手里。所以李力准备找一个靠谱的中介,通过中介,他省去很多麻烦的细节,合同也是跟中介签的,甚至不知道房东是谁!
我们通过程序来模拟上面找房子的过程。

class HouseInfo:
    """房源信息"""

    def __init__(self, area, price, hasWindow, hasBathroom, hasKitchen, address, owner):
        self.__area = area
        self.__price = price
        self.__hasWindow = hasWindow
        self.__hasBathroom = hasBathroom
        self.__hasKitchen = hasKitchen
        self.__address = address
        self.__owner = owner

    def getAddress(self):
        return self.__address

    def getOwnerName(self):
        return self.__owner.getName()

    def showInfo(self, isShowOwner=True):
        print("面积:" + str(self.__area) + "平方米",
              "价格:" + str(self.__price) + "元",
              "窗户:" + "有" if self.__hasWindow else "没有",
              "卫生间:" + self.__hasBathroom,
              "厨房:" + ("有" if self.__hasKitchen else "没有"),
              "地址:" + self.__address,
              "房东:" + self.getOwnerName() if isShowOwner else "")


class HousingAgency:
    """房屋中介"""

    def __init__(self, name):
        self.__houseInfos = []
        self.__name = name

    def getName(self):
        return self.__name

    def addHouseInfo(self, houseInfo):
        self.__houseInfos.append(houseInfo)

    def removeHouseInfo(self, houseInfo):
        for info in self.__houseInfos:
            if info == houseInfo:
                self.__houseInfos.remove(info)

    def getSearchCondition(self, description):
        """这里有一个将用户描述信息转换成搜索条件的逻辑,为节省篇幅这里原样返回描述"""
        return description

    def getMatchInfos(self, searchCondition):
        """根据房源信息的各个属性查找最匹配的信息,这里直接返回所有房源信息"""
        print(self.getName(), "为您找到以下最适合的房源:")
        for info in self.__houseInfos:
            info.showInfo(False)
        return self.__houseInfos

    def signContract(self, houseInfo, period):
        """与房东签订协议"""
        print(self.getName(), "与房东", houseInfo.getOwnerName(), "签订", houseInfo.getAddress(), "的房子的租赁合同,租期",
              period, "年。合同期内", self.getName(), "有权对其进行使用和转租!")

    def signContracts(self, period):
        for info in self.__houseInfos:
            self.signContract(info, period)


class HouseOwner:
    """房东"""

    def __init__(self, name):
        self.__name = name
        self.__houseInfo = None

    def getName(self):
        return self.__name

    def setHouseInfo(self, address, area, price, hasWindow, bathroom, kitchen):
        self.__houseInfo = HouseInfo(area, price, hasWindow, bathroom, kitchen, address, self)

    def publishHouseInfo(self, agency):
        agency.addHouseInfo(self.__houseInfo)
        print(self.getName() + "在", agency.getName(), "发布房源出租信息:")
        self.__houseInfo.showInfo()


class Customer:
    """用户,租房的贫下中农"""

    def __init__(self, name):
        self.__name = name

    def getName(self):
        return self.__name

    def findHouse(self, description, agency):
        print("我是" + self.getName() + ",我想要找一个\"" + description + "\"的房子")
        print()
        return agency.getMatchInfos(agency.getSearchCondition(description))

    def seeHouse(self, houseInfos):
        """去看房子"""
        size = len(houseInfos)
        return houseInfos[size - 1]

    def signContract(self, houseInfo, agency, period):
        """与中介签订协议"""
        print(self.getName(), "与中介", agency.getName(), "签订", houseInfo.getAddress(), "的房子的租赁合同,租期", period, "年。合同期内,",
              self.__name, "有权对其进行使用!")


def testRenting():
    myHome = HousingAgency("我爱我家")
    zhangsan = HouseOwner("张三")
    zhangsan.setHouseInfo("上地西里", 20, 2500, 1, "独立卫生间", 0)
    zhangsan.publishHouseInfo(myHome)
    lisi = HouseOwner("李四")
    lisi.setHouseInfo("当代城市家园", 16, 1800, 1, "公用卫生间", 0)
    lisi.publishHouseInfo(myHome)
    wangwu = HouseOwner("王五")
    wangwu.setHouseInfo("四季花园", 18, 2600, 1, "独立卫生间", 1)
    wangwu.publishHouseInfo(myHome)
    print()

    myHome.signContracts(3)
    print()

    lili = Customer("李力")
    houseInfos = lili.findHouse("18 平方米左右,要有独立卫生间,要有窗户,最好朝南,有厨房更好!价位在2000元左右", myHome)
    print()
    print("正在看房,寻找最合适的住巣......")
    print()
    AppropriateHouse = lili.seeHouse(houseInfos)
    lili.signContract(AppropriateHouse, myHome, 1)


if __name__ == "__main__":
    testRenting()

% python house.py

张三在 我爱我家 发布房源出租信息:
面积:20平方米 价格:2500元 窗户:有 卫生间:独立卫生间 厨房:没有 地址:上地西里 房东:张三
李四在 我爱我家 发布房源出租信息:
面积:16平方米 价格:1800元 窗户:有 卫生间:公用卫生间 厨房:没有 地址:当代城市家园 房东:李四
王五在 我爱我家 发布房源出租信息:
面积:18平方米 价格:2600元 窗户:有 卫生间:独立卫生间 厨房:有 地址:四季花园 房东:王五

我爱我家 与房东 张三 签订 上地西里 的房子的租赁合同,租期 3 年。合同期内 我爱我家 有权对其进行使用和转租!
我爱我家 与房东 李四 签订 当代城市家园 的房子的租赁合同,租期 3 年。合同期内 我爱我家 有权对其进行使用和转租!
我爱我家 与房东 王五 签订 四季花园 的房子的租赁合同,租期 3 年。合同期内 我爱我家 有权对其进行使用和转租!

我是李力,我想要找一个"18 平方米左右,要有独立卫生间,要有窗户,最好朝南,有厨房更好!价位在2000元左右"的房子

我爱我家 为您找到以下最适合的房源:
面积:20平方米 价格:2500元 窗户:有 卫生间:独立卫生间 厨房:没有 地址:上地西里 
面积:16平方米 价格:1800元 窗户:有 卫生间:公用卫生间 厨房:没有 地址:当代城市家园 
面积:18平方米 价格:2600元 窗户:有 卫生间:独立卫生间 厨房:有 地址:四季花园 

正在看房,寻找最合适的住巣......

李力 与中介 我爱我家 签订 四季花园 的房子的租赁合同,租期 1 年。合同期内, 李力 有权对其进行使用!

二、中介模式的定义

用一个中介对象来封装一系列对象交互,中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

在上面的故事剧情中,由中介来承接房客与房东之间的交互过程,可以使整个过程更加畅通、高效。这在程序中叫做中介模式,中介模式又称为调停模式。
在很多系统中,多个类很容易相互耦合,形成网状结构。中介模式的作用就是将这种网状结构(图3-1) 分离成星型结构(图3-2)。这样调整之后,使得对象间的结构更加简洁,交互更加顺畅。


图3-1 网状结构.jpg

图3-2星状结构.jpg
2.1中介模式的的模型抽象
class InteractiveObject:
    """进行交互的对象"""
    pass


class InteractiveObjectImplA:
    """实现类A"""
    pass


class InteractiveObjectImplB:
    """实现类B"""
    pass


class Meditor:
    """中介类"""

    def __init__(self):
        self.__interactiveObjA = InteractiveObjectImplA()
        self.__interactiveObjB = InteractiveObjectImplB()

    def interative(self):
        """进行交互的操作"""
        # 通过self.__interactiveObjA和self.__interactiveObjB完成相应的交互操作
        pass

Mediator就是中介类,用来协调对象间的交互,如故事剧情中的HousingAgency。InteractiveObject是要进行交互的对象,如故事剧情中的HouseOwner和Customer。InteractiveObject可以是互不相干的多个类的对象,也可以是具有继承关系的相似类。

2.2模型说明
  1. 设计要点:
    中介模式主要有以下三个角色,在设计中介模式时要找到并区分这些角色:
    (1). 交互对象(InteractiveObject),要进行交互的一系列对象。
    (2). 中介者(Mediator),负责协调各个对象之间的交互。
    (3). 具体中介者(Mediator),中介的具体实现。
  2. 应用场景
    (1). 一组对象以定义良好但复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。
    (2). 一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
    (3). 想通过一个中间类来封装多个类的行为,同时又不想生成太多的子类。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,976评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,249评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,449评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,433评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,460评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,132评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,721评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,641评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,180评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,267评论 3 339
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,408评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,076评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,767评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,255评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,386评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,764评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,413评论 2 358