• 适配模式


    适配器模式

    Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.

    将一个类的接口变成客户端所期望的另一种接口,从而使原本因接口不匹配而无法一起工作的两个类能够在一起工作。

    适配器模式的作用:

    • 接口转换,将原有的接口(或方法)转换成另一种接口;
    • 用新的接口包装一个已有的类;
    • 匹配一个老的组件到一个新的接口。

    设计思想

    适配器模式又叫变压器模式,也叫包装模式(Wrapper),它的核心思想是将一个对象经过包装或转换后使它符合指定的接口,使得调用方可以像使用这接口的一般对象一样使用它。这一思想,在我们生活中可谓是处处可见,比如变压器插座,能让你像使用国内电器一样使用美标(110V)电器;还有就是各种转接头,如 MiniDP 转 HDMI 转接头、HDMI 转 VGA 线转换器、Micro USB 转 Type-C 转接头等。

    适配器模式的类图如下:

    enter image description here

    Target 是一个接口类,是提供给用户调用的接口抽象,如上面示例中的 IHightPerson。Adaptee 是你要进行适配的对象类,如上面的 ShortPerson。Adapter 是一个适配器,是对 Adaptee 的适配,它将 Adaptee 的对象转换(或说包装)成符合 Target 接口的对象;如上面的 DecoratePerson,将 ShortPerson 的 getRealHeight 和 getShoesHeight 方法包装成 IHightPerson 的 getHeight 接口。

    模型说明

    设计要点

    适配器模式中主要三个角色,在设计适配器模式时要找到并区分这些角色:

    • 目标(Target): 即你期望的目标接口,要转换成的接口。
    • 源对象(Adaptee): 即要被转换的角色,要把谁转换成目标角色。
    • 适配器(Adapter): 适配器模式的核心角色,负责把源对象转换和包装成目标对象。

    优缺点

    适配器模式的优点
    • 可以让两个没有关联的类一起运行,起着中间转换的作用。
    • 提高了类的复用。
    • 灵活性好,不会破坏原有的系统。
    适配器模式的缺点
    • 如果原有系统没有设计好(如 Target 不是抽象类或接口,而一个实体类),适配器模式将很难实现。
    • 过多地使用适配器,容易使代码结构混乱,如明明看到调用的是 A 接口,内部调用的却是 B 接口的实现。
    class Page:
        """
        电子书一页的内容
        """
        def __init__(self,pageNum):
            self.__pageNum = pageNum
    
        def getCountent(self):
            return ""+str(self.__pageNum)+"页内容...."
    
    class CateLogue:
        """
        目录结构
        """
        def __init__(self,title):
            self.__title = title
            self.__chapters = []
            self.setChapter("第一章")
            self.setChapter("第二章")
    
        def setChapter(self,title):
            self.__chapters.append(title)
    
        def showInfo(self):
            print("标题"+self.__title)
            for chapter in self.__chapters:
                print(chapter)
    
    
    class IBook:
        """
        电子书文档的接口类
        """
        def parseFile(self,filePath):
            pass
    
        def getCatalogue(self):
            pass
    
        def getCount(self):
            pass
    
        def getPage(self,pageNum):
            pass
    
    class TxtBook(IBook):
        """
        TXT解析器
        """
        def parseFile(self,filePath):
            print(filePath+"文件解析成功")
            self.__pageCount = 500
            return True
    
        def getCatalogue(self):
            return CateLogue("TXT电子书")
    
        def getPageCount(self):
            return self.__pageCount
    
        def getPage(self,pageNum):
            return Page(pageNum)
    
    class EpubBook(IBook):
        """
        EPUB解析器
        """
        def parseFile(self,filePath):
            #模拟文档的解析
            print(filePath+"文件解析成功")
            self.__pageCount = 800
            return True
    
        def getCatalogue(self):
            return CateLogue("Epub电子书")
    
        def getPageCount(self):
            return self.__pageCount
    
        def getPage(self, pageNum):
            return Page(pageNum)
    
    class OutLine:
        """
        第三方PDF解析库的目录类
        """
        pass
    
    class PdfPage:
        """
        PDF页
        """
    
        def __init__(self,pageNum):
            self.__pageNum = pageNum
    
        def getPageNum(self):
            return self.__pageNum
    
    class ThirdPdf:
        """
        第三方PDF解析器
        """
    
        def __init__(self):
            self.__pageSize = 0
    
        def open(self,filePath):
            print("第三方解析PDF文件:"+filePath)
            self.__pageSize = 1000
            return True
    
        def getOutline(self):
            return OutLine()
    
        def pageSize(self):
            return self.__pageSize
    
        def page(self,index):
            return PdfPage(index)
    
    class PdfAdaterBook(ThirdPdf,IBook):
        """
        PDF解析类
        """
    
        def parseFile(self,filePath):
            rtn = super().open(filePath)
            if(rtn):
                print(filePath+"解析文件成功")
            return rtn
    
        def getCatalogue(self):
            outline = super().getOutline()
            print("将Outline结构的目录转换成Catalogue结构的目录")
            return CateLogue("PDF电子书")
    
        def getPageCount(self):
            return super().pageSize()
    
        def getPage(self,pageNum):
            page = self.page(pageNum)
            print("将PdfPage的对象转换成Page的对象")
            return Page(page.getPageNum())
    
    import os
    
    class Reader:
        """
        阅读器
        """
        def __init__(self,name):
            self.__name = name
            self.__filePath = ""
            self.__curBook = None
            self.__curPageNum = -1
    
        def __initBook(self,filePath):
            self.__filePath = filePath
            extName = os.path.splitext(filePath)[1]
            if extName.lower() == ".epub":
                self.__curBook = EpubBook()
            elif extName.lower() == ".txt":
                self.__curBook = TxtBook()
            elif extName.lower() == ".pdf":
                self.__curBook = PdfAdaterBook()
            else:
                self.__curBook = None
    
        def openFile(self,filePath):
            self.__initBook(filePath)
            if self.__curBook is not None:
                rtn = self.__curBook.parseFile(filePath)
                if rtn:
                    self.__curPageNum = 1
                return rtn
            return False
    
        def closeFile(self):
            print("关闭"+self.__filePath+"文件")
            return True
    
        def showCatalogue(self):
            catalogue = self.__curBook.getCatalogue()
            catalogue.showInfo()
    
        def prePage(self):
            return self.gotoPage(self.__curPageNum - 1)
    
        def nexPage(self):
            return self.gotoPage(self.__curPageNum + 1)
    
        def gotoPage(self,pageNum):
            if pageNum<1 or pageNum>self.__curBook.getPageCount():
                return None
            self.__curPageNum = pageNum
            print("显示第"+str(self.__curPageNum)+"")
            page = self.__curBook.getPage(self.__curPageNum)
            page.getCountent()
            return page
    
    if __name__ == '__main__':
        reader = Reader("阅读器")
        if not reader.openFile("平凡的世界.txt"):
            pass
    
        reader.showCatalogue()
        reader.gotoPage(1)
        reader.nexPage()
        reader.closeFile()
        print()
    
        if not reader.openFile("平凡的世界.epub"):
            pass
    
        reader.showCatalogue()
        reader.gotoPage(5)
        reader.nexPage()
        reader.closeFile()
        print()
    
        if not reader.openFile("平凡的世界.pdf"):
            pass
    
        reader.showCatalogue()
        reader.gotoPage(10)
        reader.nexPage()
        reader.closeFile()
  • 相关阅读:
    集群架构搭建
    THUWC2019 游记
    【集训队互测2015】未来程序·改
    [NOIP2014普及组T1]珠心算测验
    [CF912D]Fishes
    [POJ2409]Let it Bead
    golang 统计系统测试覆盖率
    tcpdump常用方法
    数学闯关引发的思考
    linux lsof常用方法
  • 原文地址:https://www.cnblogs.com/miaoweiye/p/12655095.html
Copyright © 2020-2023  润新知