概念解析
外观模式,是最简单也是最常用的模式,存在两个角色:
- 外观角色(Facade):为子系统封装统一的对外接口,如同子系统的门面。该类不负责具体的业务逻辑,具体业务逻辑则由子系统完成;
- 子系统(SubSystem):由多个类组成的具有特定功能的子系统:可以是第三方库,也可以是自己的基础库,还可以是子服务,为整个系统提供特定的功能或服务。
外观模式类图如下:
其优点是:
- 实现了子系统和客户端的松耦合关系,使得子系统的变化不会影响其上层的调用关系;
- 简化类客户端对子系统的使用难度:客户端不需要了解子系统的具体实现方式,而只需要和外观角色进行交互即可;
- 能够为不同用户提供统一的调用接口(整合不同的子系统),方便系统的管理和维护。
其缺点是:
- 调用接口统一一定程度上降低了系统功能的灵活性。
常用的应用场景如下:
- 为一个复杂系统提供一个简单的应用接口;
- 客户程序和各个子系统之间存在很大依赖性:引入外观类可以将子系统/客户以及其他子系统进行解耦,提高子系统的独立性和可移植性;
- 层次化结构中,多层之间可以不直接产生联系,可以通过外观类进行管理,减小各层之间的耦合度。
实例分析
场景说明:文件的压缩和解压缩,为不同格式的文件提供统一的调用接口:
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
from os import path
# 引入path进行相关文件处理
import logging
# 引入logging,进行日志处理
class ZipModel():
"""Zip模块,负责Zip文件的压缩片和解压缩:这里只进行简单模拟"""
def compress(self, src_file_path, dst_file_path):
print("Zip模块正在进行"%s"文件的压缩..." % src_file_path)
print("文件压缩成功,已保存在"%s"" % dst_file_path)
def decompress(self, src_file_path, dst_file_path):
print("Zip模块正在进行"%s"文件的解压缩..." % src_file_path)
print("文件解压缩成功,已保存在"%s"" % dst_file_path)
class RarModel():
"""Rar模块,负责rar文件的压缩片和解压缩:这里只进行简单模拟"""
def compress(self, src_file_path, dst_file_path):
print("Rar模块正在进行"%s"文件的压缩..." % src_file_path)
print("文件压缩成功,已保存在"%s"" % dst_file_path)
def decompress(self, src_file_path, dst_file_path):
print("Rar模块正在进行"%s"文件的解压缩..." % src_file_path)
print("文件解压缩成功,已保存在"%s"" % dst_file_path)
class ZModel():
"""7z模块,负责rar文件的压缩片和解压缩:这里只进行简单模拟"""
def compress(self, src_file_path, dst_file_path):
print("7z模块正在进行"%s"文件的压缩..." % src_file_path)
print("文件压缩成功,已保存在"%s"" % dst_file_path)
def decompress(self, src_file_path, dst_file_path):
print("7z模块正在进行"%s"文件的解压缩..." % src_file_path)
print("文件解压缩成功,已保存在"%s"" % dst_file_path)
class CompressionFacade():
"""压缩系统的外观类"""
def __init__(self):
self.__zip_model = ZipModel()
self.__rar_model = RarModel()
self.__7z_model = ZModel()
def compress(self, src_file_path, dst_file_path, type):
"""根据不同的压缩类型:压缩成不同的格式"""
# 获取文件名
ext_name = "." + type
full_name = dst_file_path + ext_name
if type.lower() == "zip":
self.__zip_model.compress(src_file_path, full_name)
elif type.lower() == "rar":
self.__rar_model.compress(src_file_path, full_name)
elif type.lower() == "7z":
self.__7z_model.compress(src_file_path, full_name)
else:
logging.error("Not support this format:" + str(type))
return False
return True
def decompress(self, src_file_path, dst_file_path):
"""从src_file_path获取后缀,根据不同后缀名,进行不同格式的解压缩"""
base_name = path.basename(src_file_path)
ext_name = base_name.split(".")[1]
if ext_name == "zip":
self.__zip_model.decompress(src_file_path, dst_file_path)
elif ext_name == "rar":
self.__rar_model.decompress(src_file_path, dst_file_path)
elif ext_name == "7z":
self.__7z_model.decompress(src_file_path, dst_file_path)
else:
logging.error("Not support this format:" + str(ext_name))
return False
return True
def testCompression():
facade = CompressionFacade()
facade.compress("test.md",
"test.zip")
facade.decompress("test.zip",
"test.md")
facade.compress("test.pdf",
"test.rar")
facade.decompress("test.rar",
"test.pdf")
facade.compress("test.doc",
"test.7z")
facade.decompress("test.7z",
"test.doc")