python设计模式中的适配模式

设计要点

适配器模式中主要有三个角色,在设计适配器模式时要找到并区分这些角色:
1 目标:即你期望的目标接口,要转换成的接口
2 源对象:即要被转换的角色,要把谁转换成目标角色
3 适配器:适配器模式的核心角色,负责把源对象转换和包装成目标对象

实战应用

下面为电子阅读器的项目,研发之初只支持TXT和EPUB格式的电子书,但是上线半年后又希望可以找支持pdf格式,而pdf需要使用第三方库,而第三方库和之前两类的接口并不相同,这时需要对pdf的解析库进行适配。

class Page:
    '''电子书一页的内容'''
    def __init__(self,pageNum):
        self.__pageNum = pageNum

    def getContent(self):
        return "第" + str(self.__pageNum) + "页的内容"

class Catalogue:
    '''目录结构'''
    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 getCatelogue(self):
        pass

    def getPageCount(self):
        pass

    def getPage(self,pageNum):
        pass

class TxtBook(IBook):
    '''txt解析类'''
    def parseFile(self,filePath):
        '''模拟文档的解析'''
        print(filePath + "文件解析成功")
        self.__pageCount = 500
        return True

    def getCatelogue(self):
        return Catalogue("TXT电子书")

    def getPageCount(self):
        return self.__pageCount

    def getPage(self,pageNum):
        return Page(pageNum)

class EpubBook(IBook):
    '''TXT解析类'''
    def parseFile(self,filePath):
        print(filePath+"文件解析成功")
        self.__pageCount = 800
        return True

    def getCatelogue(self):
        return Catalogue("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 PdfAdapterBook(ThirdPdf,IBook):
    '''txt解析类'''

    def parseFile(self,filePath):
        rtn = super().open(filePath)
        if(rtn):
            print(filePath + "文件解析成功")
        return rtn

    def getCatelogue(self):
        outline = super().getOutline()
        print("将Outline结构目录转换成Catelogue结构的目录")
        return Catalogue("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 = PdfAdapterBook()
        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.getCatelogue()
        catalogue.showInfo()

    def prePage(self):
        return self.gotoPage(self.__curPageNum - 1)

    def nextPage(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.getContent()
        return page
'''测试代码'''
def testReader():
    reader = Reader("阅读器")
    if(not reader.openFile("平凡的世界.txt")):
        return
    reader.showCatalogue()
    reader.gotoPage(1)
    reader.nextPage()
    reader.closeFile()
    print()

    if(not reader.openFile("平凡的世界.epub")):
        return
    reader.showCatalogue()
    reader.gotoPage(5)
    reader.nextPage()
    reader.closeFile()
    print()

    if(not reader.openFile("平凡的世界.pdf")):
        return
    reader.showCatalogue()
    reader.gotoPage(10)
    reader.nextPage()
    reader.closeFile()

testReader()
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python并没有内置的适配模式,但是可以使用一些设计模式来实现类似的功能。其一种常见的方式是使用组合和继承来实现适配模式。 在Python,可以通过创建一个适配器类来实现适配模式适配器类将目标类与被适配类进行连接,使它们能够一起工作。 适配器类通常会继承目标抽象类或实现目标接口,并且在其内部持有一个被适配类的实例。适配器类会将目标接口的方法调用转发给被适配类的对应方法,从而实现了适配模式的效果。 需要注意的是,在使用适配模式时,应该遵循以下几点: 1. 适配器类只能适配一个被适配类,不能同时适配多个被适配类。 2. 被适配类不能为最终类,否则无法进行适配。 3. 目标抽象类只能为接口,不能为类。 总的来说,适配模式可以帮助我们将一个类的接口转换成客户希望的另一个接口,从而使得原本由于接口不兼容而不能一起工作的类可以一起工作。在Python,可以使用组合和继承来实现适配模式。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [python-适配模式](https://blog.csdn.net/weixin_33717298/article/details/93866136)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Python设计模式——适配模式](https://blog.csdn.net/weixin_45455015/article/details/127557479)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值