外观模式 - GeHaha/PythonLibrary GitHub Wiki

外观模式

什么是外观模式

将复杂的业务通过一个对接人来提供一整套统一的(一条龙式的)服务,让用户不用关心内部复杂的运行机制。这种方式在程序中叫外观模式,也是门面模式。

为子系统中的一组接口提供一个一致的界面称为外观模式,外观模式定义了一个高层接口,这个接口使得这一子系统更容易使用。

  • 外观模式的核心思想
用一个简单的接口来封装一个复杂的系统,使这个系统更容易使用。

外观模式的模型抽象

外观模式的类图

类图

Facade封装了子系统额复杂实现,给外部提供了一个统一的接口,用户通过Facade来访问子系统。

降低系统的耦合度

在软件的层次化结构设计中,可以使用外观模式来定义每一层系统的调用接口,层与层之间不直接产生练习,而通过外观类建立联系,降低层之间的耦合度。

层次图

模型说明

  • 设计要点
外观模式是最简单的设计模式之一,只有两个角色

外观角色

为子系统封装统一的对外接口,如同子系统的一个门面。这个类一般不负责具体的业务逻辑,只是一个委托类,具体的业务逻辑有子系统完成。

子系统

由多个类组成的具有某一特定功能的子系统,可以是第三方库,也可以是自己的基础库,还可能是一个子服务,为整个系统提供特定的功能或服务。
  • 优缺点

优点

  1. 实现了子系统与客户端之间的松耦合关系,这使得子系统的变化不会影响到调用它的客户端。
  2. 简化了客户端对子系统的使用难度,客户端(用户)无须关心子系统的具体实现方式,而只需要和外观进行交互即可。
  3. 为不同的用户提供了统一的调用接口,方便了系统的管理和维护。

缺点

  1. 因为统一了调用的接口,降低了系统功能的灵活性。
  • 应用场景
  1. 当要为一个复杂子系统提供一个简单接口时;
  2. 客户程序与多个子系统之间存在很大的依赖性,引入外观类将子系统与客户以及其他子系统解耦,可以提高子系统的独立性和可移植性;
  3. 在层次化结构中,可以使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度。
  • 实战应用

文件的压缩与解压是一项非常重要的功能,它不仅能降低文件的存储空间,还能减少网络带宽,现在最常用的压缩文件格式有:ZIP、RAR、7Z 。从压缩率看:ZIP < RAR < 7Z(即 7Z 的压缩比最高),从压缩时间看:ZIP < RAR < 7Z(即 ZIP 的压缩速度最快)。从普及率上看,ZIP 应该是应用最广泛的,因为出现的时间最早,格式开放且免费;而 7Z 因为其极高的压缩比和开放性,大有赶超之势。 假设我们有一个压缩与解压缩系统专门处理文件的压缩和解压,这个系统有三个模块 ZIPModel、RARModel、ZModel 分别处理 ZIP、RAR、7Z 三种文件格式的压缩与解压。现在这一系统要提供给上层应用程序使用。 为了让这一系统更方便使用,这时就可以用外观模式进行封装,定义一套统一的调用接口,我们用代码实现一下。

`# -- coding: utf-8 -- """ Created on Tue Sep 25 20:17:55 2018

@author: Gehaha """

from os import path import logging

class ZIPModel: "ZIPZ模块,负责zip文件的压缩与解压" def compress(self,srcFilePath,dstFilePath): print("ZIP模块正在进行'" + srcFilePath + "'文件的压缩....") print("文件压缩成功,以保存至 '" + dstFilePath + "'")

def decompress(self,srcFilePath,dstFilePath):
    print("ZIP 模块正在进行'" + srcFilePath + "'文件的解压....")
    print("文件压缩成功,以保存至 '" + dstFilePath + "'")

class RARModel: "RAR模块,负责zip文件的压缩与解压"

def compress(self,srcFilePath,dstFilePath): 
    print("RAR模块正在进行'" + srcFilePath + "'文件的压缩....")
    print("文件压缩成功,以保存至 '" + dstFilePath + "'")
    
def decompress(self, srcFilePath, dstFilePath):
    print("RAR模块正在进行 '" + srcFilePath + "' 文件的解压......")
    print("文件解压成功,已保存至 '" + dstFilePath + "'")

class ZModel:

"7Z模块,负责7Z文件的压缩与解压"
def compress(self, srcFilePath, dstFilePath):
    print("7Z模块正在进行 '" + srcFilePath + "' 文件的压缩......")
    print("文件压缩成功,已保存至 '" + dstFilePath + "'")

def decompress(self, srcFilePath, dstFilePath):
    print("7Z模块正在进行 '" + srcFilePath + "' 文件的解压......")
    print("文件解压成功,已保存至 '" + dstFilePath + "'")

class CompressionFacade: "压缩系统的外观类"

def __init__(self):
    self.__zipModel = ZIPModel()
    self.__rarModel = RARModel()
    self.__zModel = ZModel()
    
def compress(self,srcFilePath,dstFilePath,type):
    "根据不同的压缩类型,压缩成不同的格式"
    #获取新的文件名
    extName = '.' + type
    fullName = dstFilePath + extName
    if (type.lower() == "zip"):
        self.__zipModel.compress(srcFilePath,fullName)
    elif (type.lower() == "rar"):
        self.__rarModel.compress(srcFilePath,fullName)
    elif (type.lower() == "7z"):
        self.__zModel.compress(srcFilePath,fullName)
    else:
        logging.error("Not support this format:" + str(type))
        return  False
    return True
def decompress(self,srcFilePath,dstFilePath):
    "从srcFilePath中获取后缀,根据不同的后缀名(拓展名),进行不同格式的压缩"
    baseName = path.basename(srcFilePath)
    extName = baseName.split(".")[1]
    if (extName.lower() =='zip'):
        self.__zipModel.decompress(srcFilePath, dstFilePath)
    elif(extName.lower() == "rar"):
        self.__rarModel.decompress(srcFilePath, dstFilePath)
    elif(extName.lower() == "7z"):
        self.__zModel.decompress(srcFilePath, dstFilePath)
    else:
        logging.error("Not support this format:" + str(extName))
        return False
    return True

def testCompression(): facade = CompressionFacade() facade.compress("E:\生活中的设计模式\生活中的外观模式——学妹别慌,学长帮你.md", "E:\压缩文件\生活中的外观模式——学妹别慌,学长帮你", "zip") facade.decompress("E:\压缩文件\生活中的外观模式——学妹别慌,学长帮你.zip", "E:\解析文件\生活中的外观模式——学妹别慌,学长帮你.md") print()

facade.compress("E:\生活中的设计模式\生活中的外观模式——学妹别慌,学长帮你.md",
                "E:\压缩文件\生活中的外观模式——学妹别慌,学长帮你", "rar")
facade.decompress("E:\压缩文件\生活中的外观模式——学妹别慌,学长帮你.rar",
                  "E:\解析文件\生活中的外观模式——学妹别慌,学长帮你.md")
print()

facade.compress("E:\生活中的设计模式\生活中的外观模式——学妹别慌,学长帮你.md",
                "E:\压缩文件\生活中的外观模式——学妹别慌,学长帮你", "7z")
facade.decompress("E:\压缩文件\生活中的外观模式——学妹别慌,学长帮你.7z",
                  "E:\解析文件\生活中的外观模式——学妹别慌,学长帮你.md")
print()     

`