案例分析:设计模式与代码的结构特性

简单工厂模式,通过工厂类提供的方法,传入参数,工厂方法根据参数判断要创建什么样的对象返回

 

工厂方法模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。创建一个工厂接口,具体实现是由其实现类实现。

抽象工厂模式:抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类

 

引用关键代码,解释该设计模式在该应用场景中的适用性:

工厂模式:

#创建一个区块工厂类
class BlockFactory():
    def newBlock(self,data,prevBlockHash):
        #生成一个默认区块对象
        block = Block(time.time(),data,prevBlockHash,"")
        #获取并设置该区块hash
        block.setHash()
        return block
#创建一个创世区块工厂类
class GenesisBlockFactory():
    #新生成一个创世区块
    def mineNewBlock(self,data,prevBlockHash):
        block = self.newBlock(data,prevBlockHash)
        #开始挖矿,要求前n位数值为零,以此作为工作量证明
        nonce,hashedData = work.runNewProofOfWork(block)
        block.hash = hashedData
        block.nonce = nonce
        return block
    #将创世区块加入到区块链中
    def addBlock(self,data,lasthash,mine=False):
        for tx in data:
            if not self.verifyTransaction(tx):
                print("ERROR: Invalid transaction")
        #如果不挖区块
        if mine == False:
            newBlock = factory.newBlock(data,lasthash)
            self.blocks+=[newBlock]
        else:
            newBlock = factory.mineNewBlock(data,lasthash)
            self.blocks+=[newBlock]
    #新挖一个创世区块
    def newGenesisBlock(self,data,mine=False):
        for tx in data:
            #矿工验证交易正确性
            if not self.verifyTransaction(tx):
                print("ERROR: Invalid transaction")
        if mine == False:
            newBlock = factory.newBlock(data,"")
            self.blocks+=[newBlock]
        else:
            newBlock = factory.mineNewBlock(data,"")
            self.blocks+=[newBlock]
#生成区块
block = BlockFactory().newBlock(...)
#生成创世区块
GenesisBlock = GenesisBlockFactory().newBlock(...)

 

抽象工厂:

#工厂方法虽然解决了我们“修改代码”的问题,但如果我们要生产很多产品,就会发现我们同样需要写很多对应的工厂类。比如如果Factory不仅生产block,还要生产GenesisBlock等,这样需要建造多个生产类。所以为了解决这个问题,我们就要再更进一步的抽象工厂类,让一个工厂可以生产同一类的多个产品,这就是抽象工厂。
class AbstractFactory(object):
    @abc.abstractmethod
    def productBlock(self):
        pass

    @abc.abstractmethod
    def productGenesisBlock(self):
        pass    
class Factory(AbstractFactory):
    def productBlock(self):
        return Block(time.time(),data,prevBlockHash,"")
    def productGenesisBlock(self):
         block = self.newBlock(data,prevBlockHash)
        nonce,hashedData = work.runNewProofOfWork(block)
        block.hash = hashedData
        block.nonce = nonce       
        return block  
b1 = Factory().productBlock()
b2 = Factory().productGenesisBlock()
#抽象工厂模式与工厂方法模式最大的区别在于,抽象工厂中的一个工厂对象可以负责多个不同产品对象的创建 ,这样比工厂方法模式更为简单、有效率。

 

引入该设计模式后对系统架构和代码结构带来了哪些好处:

  • 用户不需要关心如何去查找和创建具体类的实现。

  • 不同对象创建由工厂的实现类实现,实现解耦。

  • 符合开闭原则,对修改封闭,对扩展开放,需要新增工厂,只需新增一个具体的工 厂实现。

  • 用户不需要关注block(),GenesisBlock()具体实现,通过创建工厂实现来获得对象

  • 用户只能根据BlockFactory(),GenesisBlockFactory()实现去获得对象。不会存在或得不到对象的情况

解释其中用到的多态机制

  • 多态:在运行期根据实际类型确定方法执行版本的分派动作。Factory继承AbstractFactory,复用productBlock、productGenesisBlock方法。

    调用方只管调用,不管细节,而当我们新增一种Factory的子类时,只要确保productBlock()方法编写正确,不用管原来的代码是如何调用的。这就是著名的“开闭”原则:

    对扩展开放:允许新增AbstractFactory子类;

    对修改封闭:不需要修改依赖AbstractFactory类型的productBlock()等函数。

说明模块抽象封装的方法

 #新加入一个区块,对于需要创建不同区块的工厂,复用这个抽象封装函数,实现自己的创建过程
 @abc.abstractmethod
 def productBlock(self):
     pass
 #新生成一个创世区块,对于需要生成不同创世区块的工厂,复用这个抽象封装函数,实现自己的创建创世区块过程
 @abc.abstractmethod
 def productGenesisBlock(self):
     pass   

分析各个模块的内聚度和模块之间的耦合度

  • 不同对象创建由工厂的实现类实现,实现解耦。

  • 而 AbstractFactory更进一步解耦,用户使用过程中只关心工厂提供的选择,不需要额外关注productGenesisBlock、productBlock等功能具体由哪个工厂实现。提供该应用范例完整的源代码包括构建部署的操作过程

提供该应用范例完整的源代码包括构建部署的操作过程

完整源代码:

https://github.com/yummybian/blockchain-py

部署过程:

https://bigishdata.com/2017/10/17/write-your-own-blockchain-part-1-creating-storing-syncing-displaying-mining-and-proving-work/

参考:

https://liuchengxu.gitbook.io/blockchain/bitcoin/basic-prototype

posted @ 2019-12-07 13:57  muddyway  阅读(218)  评论(0编辑  收藏  举报