2017-06-15 25 views
1

我正在處理一個嚴重依賴於基本代碼庫的項目。在基礎代碼,也定義了一個名爲eventWatcher轉:接口中的可選方法

//Baselibrary.go: 
    package base 
    type eventHandle interface { 
     eventHookTypeA 
     eventHookTypeB 
     someOtherMethod() results 
    } 
    type eventHookTypeA interface { 
     // method definitions 
     HandleEventA() results 
    } 
    type eventHookTypeB interface { 
     // method definitions 
     HandleEventB() results 
    } 

    func handleEvents(eventType string, handle eventHandle) results { 
      if eventType == "eventA" { 
      return handle.HandleEventA() 
      } else if eventType == "eventB" { 
      return handle.HandleEventB() 
      } 
      return nil 
    } 

對於我們的項目的接口(這裏的簡化),我們現在havee第三事件類型(例如,eventTypeC)即排到我們的項目。一種方法是在基類中添加第三個接口定義(eventHookTypeC),並在我們自己的項目代碼中相應地執行。然而,我們的CI環境也將採用這個新版本的Baselibrary.go,並用它構建所有其他項目,這將失敗,因爲它們將缺少eventHookTypeC的impl。

除了改變我們的構建環境或回購,有沒有Go的解決方法,而不必更改其他項目的代碼?

回答

7

您可以按照與完成相同的方式來完成此操作。 http.Pusherio.Closer。您使用「可選」方法創建一個新界面,並傳遞原始界面。當你想執行可選方法時,你使用一個類型斷言來檢查你的值是否實現了另一個接口,如果是,則調用該方法。

type eventHandle interface { 
    eventHookTypeA 
    eventHookTypeB 
    // DON'T add TypeC interface. 
    someOtherMethod() results 
} 
type eventHookTypeA interface { 
    // method definitions 
    HandleEventA() results 
} 
type eventHookTypeB interface { 
    // method definitions 
    HandleEventB() results 
} 
type eventHookTypeC interface { 
    HandleEventC() results 
} 

func handleEvents(eventType string, handle eventHandle) results { 
     if eventType == "eventA" { 
     return handle.HandleEventA() 
     } else if eventType == "eventB" { 
     return handle.HandleEventB() 
     } else if eventType == "eventC" { 
     if c,ok := handle.(eventHookTypeC); ok { 
      return c.HandleEventC() 
     } else { 
      log.Println("somewhat bad happen") 
     } 
     } 
     return nil 
}