2014-08-30 125 views
0

假设我们有一个包含以下XML文件:在这种情况下如何避免多继承?

<document> 

    <tagA /> 
    <tagB /> 
    <tagC /> 
    <tag1 /> 
    <tag2 /> 
    <tag3 /> 
    <custom1/> 
    <custom2/> 

</document> 

,并假设我们有一个解析器对象扫描该文件。对于文件中找到的每个标签解析器调用处理程序对象的相应方法:

class Handler{ 

    function tagA(){ ... } 
    function tabB(){ ... } 
    function tagC(){ ... } 
    function tag1(){ ... } 
    function tag2(){ ... } 
    function tag3(){ ... } 
    function custom1(){ ... } 
    function custom2(){ ... } 

} 

现在,假设我们要建立一个框架来处理上述类型的文件。为了确保代码的可重用性,我们可以在上面的类分成不同的(更专业)类:

class LettersHandler{ 

    function tagA(){ ... } 
    function tabB(){ ... } 
    function tagC(){ ... } 

} 

class NumbersHandler{ 

    function tag1(){ ... } 
    function tag2(){ ... } 
    function tag3(){ ... } 

} 

要为上述文件代码的处理程序,程序员可以采取框架的优势,只实现了缺失的方法(使用OOP继承):

class Handler extends LettersHandler, NumbersHandler{ 

    function custom1(){ ... } 
    function custom2(){ ... } 

} 

根据该文件的内容,程序员可以选择只从一个类继承,从两个(如上面的例子),或无。

现在,假设该框架支持许多预先建立一个处理程序:

class LettersHandler{ ... } 
class NumbersHandler{ ... } 
class SymbolsHandler{ ... } 
etc... 

如果编程语言支持多重继承,程序员可以从该框架提供一个或多个类继承来处理特定的文件(根据文件中包含的标签)。

现在,我的问题是:

什么是实现上述情况,如果编程语言不支持多重继承的最好方式,但只支持单继承?

有没有一种简单的方法来使用多重继承?

我读过多继承通常被认为是不好的做法,但我真的不明白如何实现上述情况而不使用它。

回答

0
  1. 创建一个名为TagHandler的基类。

    // A C++ incarnation of such a class. 
    class TagHandler 
    { 
        virtual processTag(std::string const& tagName, 
             ..., // Any additional arguments that makes sense 
            ) = 0; 
    
    }; 
    
  2. 提供一种机制,为客户基于标签名注册TagHandler秒。做出一些关于如何处理给定标签名称的多个客户端注册处理程序的策略决策。你想举一个例外吗?最后一个赢了吗?你是否允许多个TagHandlers?

    class TagProcessor 
    { 
        public: 
        static void registerTagHandler(std::string const& tagName, 
                TagHandler* tagHandler) 
        { 
         // Do the needful to register the TagHandler based on policy. 
        } 
    }; 
    
  3. 提供在上面的类中以黑匣子方式处理标签的函数。

    class TagProcessor 
    { 
        public: 
    
        static void processTag(std::string const& tagName, 
              ..., // Any additional arguments that makes sense 
              ) 
        { 
         // Look for the TagHandler(s) given the tag name. 
         // If found, call the processTag() function. 
         // Deal with non-existing TagHandler. 
        } 
    
    
    }; 
    
  4. 加工各种标签创建的子类型TagHandler

    class TagAHandler : public TagHandler 
    { 
        public: 
        virtual processTag(std::string const& tagName, 
             ...) 
        { 
         // Do the needful to process the tag 
        } 
    }; 
    
  5. 注册TagHandler是对付 “塔加”

    TagProcessor::register("tagA", new TagHandler()); 
    
  6. 呼叫TagProcessor::processTag在解析器代码。

0

更改解析器,使其接受一个处理程序数组而不是一个处理程序,然后让它为每个标记依次调用每个处理程序。如果处理程序无法处理标记(通过测试方法的存在,或者基类的方法返回一些“未实现”的sigil值),则调用下一个处理程序。

如果无法修改解析器,请实现一个新的处理程序,它接受处理程序数组并将其委托给它们,就像它是上述修改过的解析器一样。

这实质上是将结构从程序的类型移动到程序数据中的结构。

相关问题