2013-03-11 59 views
5

我們在svn下有我們的項目,一切都很順利。最近一位主要客戶要求我們爲他們做一些非常具體的定製,這需要編碼和內容(無法使用配置或部署完成)。我們決定維持發展的兩條線:在svn下維護兩條非常接近但又獨立的開發線?

  • trunk分支是部署 普通客戶
  • arsh分支這位客戶並正在不斷髮展我們的標準版從分離是怎麼回事就在trunk

現在就是arsh應該countinually從trunk接收更新,有時特徵arsh實現的是USEF ul在trunk。這種關係有點雙向,但一個方向是相當普遍的(從trunkarsh),但另一個是偶然的。

這樣做的最好方法是什麼?工作流程 ?最佳實踐?見解?

編輯:我們使用PHP 5.3,MySQL,Apache和Linux。

回答

3

最佳做法? (或者通過運行時配置或任何其他編譯時或運行時條件,有條件地包含或條件依賴注入的相同接口的單獨實現)!

將並行版本作爲分支維護是任何版本控制系統中的難題。並行版本最好使用適當的條件編譯或運行時配置技術進行維護。請記住,如果您將分支A合併到分支B,並將分支B合併回分支A,那麼兩個分支將完全相同。這是3路合併的內在屬性。它正是你想要的功能分支,但它完全不適合爲不同的客戶維護並行版本。

爲了保留不同客戶的版本,而不是使用條件編譯。

  • 在面向對象的代碼,通常可以有基類與普通邏輯和每變種定製派生類只特定於不論有條件包含在項目或條件實例化的變體的邏輯。
  • 大多數編程語言都支持某種形式的條件編譯,Java是值得注意的例外。

這種方法讓所有人總是立即檢查他們沒有爲任何變異,可以通過運行於所有變體測試或有建造和持續集成服務器測試的所有變種破壞任何功能。

你提到PHP。這裏沒有編譯步驟,所以配置只是運行時。我可能會創建一個具有客戶特定覆蓋的目錄,這些目錄將有條件地包含在適當的模板中。

注意:我目前正在研究一個C++項目,這個項目是以這種方式爲超過20位客戶定製的,並且它可以很好地擴展。我們沒有完全針對每個客戶的代碼,而是我們有一組可選的功能,並將不同的子集發送給不同的客戶。這使得測試所有功能變得容易一些,因爲我們可以構建最大變體並測試它。這有助於您發展到大量功能,特別是如果您的項目需要很長時間才能構建(我們的持續集成構建運行大約一個小時,每晚構建8個小時,並且構建所有客戶變體需要超過一整天)。

0

您沒有提及您的語言,但假設您使用的是面嚮對象語言,請考慮將您的自定義功能保留在相同接口和/或基類的單獨實現中,並在運行時使用工廠決定運行哪個實施。例如(在C#):

public interface IProcessor { 
    void ProcessFile(string fileName); 
} 

public abstract class BaseProcessor : IProcessor { 
    void IProcessor.ProcessFile(string fileName) { 

     // Do shared stuff here like logging, validation, etc. 

     ProcessFileForClient(fileName); 
    } 
    protected abstract void ProcessFileForClient(string fileName); 
} 

public class NormalProcessor : BaseProcessor { 
    protected override void ProcessFileForClient(string fileName) { 
     // Do your normal routine here 
    } 
} 

public class AcmeProcessor : BaseProcessor { 
    protected override void ProcessFileForClient(string fileName) { 
     // Do your custom stuff here 
    } 
} 

// This can be as complex as you need - you should probably use an IoC/DI framework, 
// but this is a simple example. 
public static class ProcessorFactory { 
    public static IProcessor GetProcessor(string clientCode) { 
     switch (clientCode) { 
      case "Acme": return new AcmeProcessor(); 
      default: return new NormalProcessor(); 
     } 
    } 
} 

這種方法有讓您的自定義代碼出於對您的正常代碼的方式,同時還允許你分享,就像你會在基類喜歡的好處。

+0

只要您可以將單獨的版本發送給不同的客戶,我寧願只編譯代碼中的相應實現。即在同一個名字下有多個實現,有條件地包含在項目中。 C#也有條件編譯,如果差異很小,這是最合適的。 – 2013-03-11 14:47:56

+0

@JanHudec非常真實 - 我想這隻取決於環境。如果你正在處理一個基於Web或基於服務的應用程序,它並不重要。但是打包產品,你的條件編譯可能是更好的選擇。 – 2013-03-11 14:54:45