技术开发 频道

访问者模式-Visitor 学习与思考

[IT168 技术文档]终于可以闲会了,继续研究设计模式,这次是Visitor ,访问者模式。照例先看李建忠老师的视频,然后看GOF的原文,从不明白的郁闷,到反复看了之后的恍然,然后又有了点疑问。

先说我的理解,访问者模式有2个参与者,一个访问者,一个被访问者。访问者是一组操作的集合,对他所知的被访问者进行操作。

访问者模式有2个重点,1 已知被访问者,就是说访问者只能访问有限的对象,如果所访问的对象增加了,那么就要修改访问者了,2 被访问者必须有个统一的被访问接口。

看GOF画的结构图,Visitor类就是访问者,Visitor类拥有几个方法是固定的,不同的方法访问不同的被访问者,我说的一个重点就是在这里体现,如果不幸有第三个对象需要访问,那么就只能修改Visitor类了,李建忠老师在视频里也说这是访问者模式的缺陷。而Element类就是被访问者了,它只有一个方法,接受Visitor类型参数的Accept方法,也就是所有被访问者统一的被访问接口,当然,实际上它还有自己的其他方法。

接着看,问题来了,这个ObjectStructure干什么的?GOF原图上干干净净的,李老师的视频也没提它,我就找了Terrylee版的C#设计模式来看,Terrylee对ObjectStructure的描述是一个统一调用被访问者的容器,语言不好描述,贴原码如下:
// "ObjectStructure" 
class ObjectStructure 

    
private ArrayList elements = new ArrayList(); 

    
public void Attach(Element element) 
    

        elements.Add(element); 
    }
 
    
    
public void Detach(Element element) 
    

        elements.Remove(element); 
    }
 
    
    
public void Accept(Visitor visitor) 
    

        
foreach (Element e in elements) 
        

            e.Accept(visitor); 
        }

    }
 
}
 

个人觉得,这样理解恐怕不是很正确,我觉得这个ObjectStructure应该是一个相当自由的类,Visitor模式的变化就体现在这里,就是说如果增加了新的行为(给Visitor增加了新的子类),那么就应当在这里调用,而调用的方式不应当是这样固定的,应该是自由组合的。

    //客户程序,变,如果增加新的Visitor,可以在这里体现
    public class ObjectStructure
    
{
        
public void Process()
        
{
            
//访问者总数是不固定的,而使用也是需要则生成,不需要不生成
            
//在一个类里,不一定都用到,也可能不会只用一个
            ConcreteVisitorA va = new ConcreteVisitorA();
            ConcreteVisitorB vb 
= new ConcreteVisitorB();

            
//被访问者总数是固定的,总是这些
            
//在一个类里,不一定都用到,也可能不会只用一个
            ConcreteElementA ca = new ConcreteElementA();
            ConcreteElementB cb 
= new ConcreteElementB();

            
//对于放问者和被访问者的组合,应当是自由的,任意组合的

            ca.Accept(va);
            cb.Accept(va);

            
//

            ca.Accept(vb);
            cb.Accept(vb);
            
            
//
        }

    }


正是因为这个ObjectStructure这么自由,所以GOF的图中没有给出任何相关结构,呵呵,胡乱猜想,大家别笑。

0
相关文章