Python的结构型设计模式之外观模式

来源:互联网 发布:淘宝美工书籍推荐 编辑:程序博客网 时间:2024/05/21 11:09
书上说:如果某套接字因为太过于复杂或太专注于底层细节而变得不易使用,那么可考虑用“外观模式”将其简化并统合起来
讲真的,后面的享元模式和代理模式还好点,这一个外观模式,我怎么看也就是那样:虽然这次没有类继承类,但A方法里面用B方法,在下面实现B方法。这里我个人总结的就是这么回事呐。
此次的例子是设计一套简单而一致的接口来获知压缩文档里的各个文件名,并将其解压。
概括起来就是,定义一个方法类用来解压一个压缩文件名,打印包含的文件名,并提供解压到当前目录的功能。
class Archive:    def __init__(self, filename):        self._name = None        self._unpack = None        self._file = None        self.filename = filename
因此定义的属性为 name(文件名),unpack(解压到当前目录的对象),file(打开文件的对象),filename 只读属性,压缩文件名。


    @property    def filename(self):        return self.__filename    @filename.setter    def filename(self, name):        self.close()        self.__filename = name    def close(self):        if self._file is not None:            self._file.close()        self._names = self._unpack = self._file = None    def __enter__(self):        return self    def __exit__(self, exc_type, exc_val, exc_tb):        self.close()    def names(self):        if self._file is None:            self._prepare()        return self._unpack    def unpack(self):        if self._file is None:            self._prepare()        return self._unpack    def _prepare(self):        if self.filename.endswith((".tar.gz", ".tar.bz2", ".tar.xz", ".zip")):            self._prepare_tarball_or_zip()        elif self.filename.endswith(".gz"):            self._prepare_gzip()        else:            raise ValueError("unreadable: {}".format(self.filename))
1.打开文件了肯定要关闭
2.获取压缩包内的文件名
3.解压压缩包
4.为实现具体功能提供统一方法

    def _prepare_tarball_or_zip(self):        def safe_extractall():            unsafe = []            for name in self.names():                if not self.is_safe(name):                    unsafe.append(name)            if unsafe:                raise ValueError("unsafe to unpack: {}".format(unsafe))            self._file.extractall()        if self.filename.endswith(".zip"):            self._file = zipfile.ZipFile(self.filename)            self._names = self._file.namelist            self._unpack = safe_extractall        else:            suffix = os.path.splitext(self.filename)[1]            self._file = tarfile.open(self.filename, "r" + suffix[1:])            self._names = self._file.getnames            self._unpack = safe_extractall    def is_safe(self, filename):        return not (filename.startswith(("/", "\\")) or (len(filename) > 1 and filename[1] == ":" and                                                         filename[0] in string.ascii_letter) or                    re.search(r"[.][.][/\\]", filename))    def _prepare_gzip(self):        self._file = gzip.open(self.filename)        filename = self.filename[:-3]        self._names = lambda :[filename]        def extractall():            with open(filename, "wb") as file:                file.write(self._file.read())        self._unpack = extractall
这是实现解压功能。都是方法里面再定义一个方法 extracall 完成其本身的价值。


这里的关键是,对于不同的压缩文档,你可以使用一个 _prepare 方法来完成。因此对于要是有更多的文件类型,只需要在 _prepare 里面添加即可。

0 0