python设计模式之访问者模式

python设计模式之访问者模式

意图

  • 封装某些作用于某种数据结构中各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作

使用场景

  • 假如一个对象中存在着一些与本对象不相干(或者关系较弱)的操作,为了避免这些操作污染这个对象,则可以使用访问者模式来把这些操作封装到访问者中去
  • 一组对象中,存在着相似的操作,为了避免出现大量重复的代码,也可以将这些重复的操作封装到访问者中去
  • 访问者模式并不是那么完美,它也有着致命的缺陷:增加新的元素类比较困难。通过访问者模式的代码可以看到,在访问者类中,每一个元素类都有它对应的处理方法,也就是说,每增加一个元素类都需要修改访问者类(也包括访问者类的子类或者实现类),修改起来相当麻烦。也就是说,在元素类数目不确定的情况下,应该慎用访问者模式。所以,访问者模式比较适用于对已有功能的重构

例子

  • 这里是个构建车的例子,每个部件都有一个accept的方法接受我上面说的所谓’访问者’,而这个访问者 以参数的方式传进来,但是其实他是一个含有一些功能的类的实例,它拥有很多个visit开头的方法对应不同的部件。 这样就不需要修改这些部件,而只是修改我们的访问者类的相关部分
# -*- coding=utf-8 -*-


class Wheel(object):
    """
    轮子,引擎, 车身这些定义好了都不需要变动
    """
    def __init__(self, name):
        self.name = name

    def accept(self, visitor):
        """
        每个visitor是同样的,但是其中的方法是不一样的,比如这里是visit_wheel,
        然后传入了self,想想?他其实想做什么就能做什么
        :param visitor:
        :return:
        """

        visitor.visit_wheel(self)


class Engine(object):
    def __init__(self):
        self.name = 'enging_name'

    def accept(self, visitor):
        visitor.visit_engine(self)


class Body(object):
    def accept(self, visitor):
        visitor.visit_body(self)


class Car(object):
    """
    我们要组合成车
    """
    def __init__(self):
        self.engine = Engine()
        self.body = Body()
        self.wheels = [Wheel("front left"), Wheel("front right"),
                       Wheel("back left"), Wheel("back right")]

    def accept(self, visitor):
        """
        这个也不需要在动,他只是上面部件的组合,只是做了属性的委托
        :param visitor:
        :return:
        """
        visitor.visit_car(self)
        self.engine.accept(visitor)
        self.body.accept(visitor)
        for wheel in self.wheels:
            wheel.accept(visitor)


class PrintVisitor(object):
    """
    访问者,每次的修改都在这里面
    """

    def visit_wheel(self, wheel):
        print "Visiting " + wheel.name + " wheel"

    def visit_engine(self, engine):
        print 'enging_name:{}'.format(engine.name)
        print "Visiting engine"

    def visit_body(self, body):
        print "Visiting body"

    def visit_car(self, car):
        print "Visiting car"


if __name__ == '__main__':
    car = Car()
    visitor = PrintVisitor()
    car.accept(visitor)


output:
Visiting car
enging_name:enging_name
Visiting engine
Visiting body
Visiting front left wheel
Visiting front right wheel
Visiting back left wheel
Visiting back right wheel
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值