it-swarm-eu.dev

Jak udržovat různé přizpůsobené verze stejného softwaru pro více klientů

máme více klientů s různými potřebami. Přestože je náš software do určité míry modularizován, je téměř jisté, že potřebujeme upravit obchodní logiku každého modulu sem a tam pro každého zákazníka trochu. Změny jsou pravděpodobně příliš malé na to, aby ospravedlňovaly rozdělení modulu na samostatný (fyzický) modul pro každého klienta, obávám se problémů s sestavením, spojovacího chaosu. Přesto jsou tyto změny příliš velké a příliš mnoho na to, aby je bylo možné nakonfigurovat pomocí přepínačů v některém konfiguračním souboru, protože by to vedlo k problémům během nasazení a pravděpodobně k mnoha problémům s podporou, zejména u správců typu drinků.

Chtěl bych, aby systém sestavení vytvořil více sestavení, jednu pro každého klienta, kde změny jsou obsaženy ve specializované verzi dotyčného jediného fyzického modulu. Mám tedy několik otázek:

Doporučili byste nechat sestavovací systém vytvořit více sestav? Jak mám ukládat různé úpravy v řízení zdroje, zejména svn?

48
Falcon

To, co potřebujete, je větvení funkcí - jako organizace kódu. Ve vašem konkrétním scénáři by se to mělo nazývat Odvětvování kmenů specifických pro klienta , protože pravděpodobně budete také používat větvení funkcí při vývoji nových věcí (nebo řešení chyb ).

http://svnbook.red-bean.com/en/1.5/svn.branchmerge.commonpatterns.html

Záměrem je sloučit kmen kódu s větvemi nových funkcí. Mám na mysli všechny funkce, které nejsou specifické pro klienta.

Pak máte také pobočky specifické pro klienta , kde také sloučíte větve stejných funkcí podle potřeby (pokud chcete, vyberete třešně).

Tyto větve klientů vypadají podobně jako větve funkcí, i když nejsou dočasné nebo krátkodobé. Jsou udržovány po delší dobu a hlavně jsou sloučeny. Měl by existovat co nejmenší vývoj větví funkcí specifických pro klienta.

Pobočky specifické pro klienta jsou paralelní větve s kmenem a jsou aktivní, pokud jsou samotné kmenem a nikde se ani nespojují jako celek.

            feature1
            ———————————.
                        \
trunk                    \
================================================== · · ·
      \ client1            \
       `========================================== · · ·
        \ client2            \
         `======================================== · · ·
              \ client2-specific feature   /
               `——————————————————————————´
8
Robert Koritnik

Nedělejte to s pobočkami SCM. Vytvořte společný kód jako samostatný projekt, který vytvoří artefakt knihovny nebo kostry projektu. Každý zákaznický projekt je samostatný projekt, který pak závisí na společném jako závislost.

To je nejjednodušší, pokud vaše běžná základní aplikace používá rámec pro závislostní injekce, jako je jaro, takže můžete snadno vstřikovat různé náhradní varianty objektů v každém zákaznickém projektu, protože jsou vyžadovány vlastní funkce. I když ještě nemáte DI framework, přidání jednoho a provedení tohoto postupu může být vaše nejméně bolestivá volba.

39
Alb

Ukládejte software pro všechny klienty v jedné větvi. Není nutné odklonit změny provedené pro různé klienty. Především budete chtít, aby byl váš software nejlepší kvality pro všechny klienty, a oprava chyby ve vaší základní infrastruktuře by měla ovlivnit každého bez zbytečného sloučení režijních nákladů, což také může přinést další chyby.

Modularizujte společný kód a implementujte kód, který se liší v různých souborech, nebo jej ochraňte pomocí různých definic. Aby váš systém sestavení měl specifické cíle pro každého klienta, každý cíl sestavuje verzi s kódem vztahujícím se pouze k jednomu klientovi. Pokud je například váš kód C, můžete chtít chránit funkce pro různé klienty pomocí „#ifdef "nebo jakýkoli mechanismus, který má váš jazyk pro správu konfigurace sestavení, a připravte sadu definic odpovídající množství funkcí, které klient zaplatil.

Pokud se vám nelíbí aplikace ifdefs, použijte „rozhraní a implementace“, „funktory“, „soubory objektů“ nebo jakékoli nástroje, které váš jazyk poskytuje pro ukládání různých věcí na jednom místě.

Pokud distribuujete zdroje svým klientům, je nejlepší zajistit, aby vaše skripty sestavení obsahovaly zvláštní „cíle distribuce zdrojů“. Jakmile vyvoláte takový cíl, vytvoří speciální verzi zdroje vašeho softwaru, zkopíruje je do samostatné složky, takže je můžete odeslat, a nekompiluje je.

13
P Shved

Jak mnozí uvedli: faktor správný kód a přizpůsobit na základě společného kód - to výrazně zlepší údržbu. Ať už používáte objektově orientovaný jazyk/systém, nebo ne, je to možné (i když v C je to mnohem obtížnější než něco, co je skutečně objektově orientované). To je přesně ten typ problému, který dědictví a zapouzdření pomáhají řešit!

8
Michael Trausch

velmi opatrně

Větvení funkcí je možnost, ale zjistil jsem, že je poněkud těžký. Také to usnadňuje hluboké úpravy, které mohou vést k vidlici přímo ve vaší aplikaci, pokud nejsou pod kontrolou. V ideálním případě chcete co nejvíce využít přizpůsobení ve snaze udržet základní kód co nejběžnější a obecný.

Zde je návod, jak bych to udělal, i když nevím, zda je použitelný pro vaši kódovou základnu bez těžkých úprav a opakování faktorů. Měl jsem podobný projekt, kde byla základní funkčnost stejná, ale každý zákazník vyžadoval velmi specifickou sadu funkcí. Vytvořil jsem sadu modulů a kontejnerů, které poté sestavím pomocí konfigurace (à la IoC).

pak jsem pro každého zákazníka vytvořil projekt, který v podstatě obsahuje konfigurace a skript sestavení, abych vytvořil plně nakonfigurovanou instalaci pro jejich web. Občas tam umístím také některé komponenty vytvořené pro tohoto klienta. Ale to je vzácné a pokaždé, když je to možné, snažím se to udělat v obecnější podobě a potlačit to dolů, aby je mohly použít i jiné projekty.

Konečným výsledkem je, že jsem dostal úroveň přizpůsobení, kterou jsem potřeboval, dostal jsem přizpůsobené instalační skripty, takže když se dostanu na web zákazníka, nevypadám, že neustále poklepávám systém a jako přidaný VELMI významný bonus dostanu být schopen vytvářet regresní testy závislé přímo na sestavení. Tímto způsobem, kdykoli dostanu chybu, která je specifická pro zákazníka, mohu napsat test, který bude prosazovat systém, jak je nasazen, a tak dokážu udělat TDD i na této úrovni.

zkrátka:

  1. Silně modularizovaný systém s rovnou strukturou projektu.
  2. Vytvořte projekt pro každý konfigurační profil (zákazník může sdílet více profilů)
  3. Sestavte požadované sady funkcí jako jiný produkt a zacházejte s nimi.

Pokud je provedeno správně, vaše sestava produktu by měla obsahovat všechny konfigurační soubory kromě několika.

Poté, co jsem to nějakou dobu použil, jsem nakonec vytvořil meta-balíčky, které sestavují nejčastěji používané nebo základní systémy jako základní jednotku a tento meta-balíček používám pro zákaznické sestavy. Po několika letech jsem skončil s velkým souborem nástrojů, který jsem mohl velmi rychle sestavit, abych vytvořil zákaznická řešení. Momentálně se dívám na Jaro Roo a uvidím, jestli nemůžu posunout myšlenku o něco dále doufat, že jednoho dne mohu vytvořit první návrh systému přímo se zákazníkem v našem prvním rozhovoru ... Asi byste to mohli nazvat User Driven Development ;-).

Doufám, že to pomohlo

5
Newtopian

Změny jsou pravděpodobně příliš malé na to, aby ospravedlňovaly rozdělení modulu na samostatný (fyzický) modul pro každého klienta, obávám se problémů s sestavením, spojovacího chaosu.

IMO, nemohou být příliš maličká. Pokud je to možné, vydělal bych kód specifický pro klienta pomocí vzoru strategie téměř všude. Tím se sníží množství kódu, který musí být rozvětven, a sníží se sloučení potřebné k udržení synchronizace obecného kódu pro všechny klienty. Zjednoduší to také testování ... můžete testovat obecný kód pomocí výchozích strategií a samostatně testovat třídy specifické pro klienta.

Pokud jsou vaše moduly kódovány tak, že použití zásady X1 v modulu A vyžaduje použití zásady X2 v modulu B, přemýšlejte o refaktoringu, takže X1 a X2 lze kombinovat do jedné třídy politik.

3
kevin cline

Pokud píšete obyčejným písmem C, je zde poměrně ošklivý způsob.

  • Společný kód (např. Jednotka „frangulator.c“)

  • kód specifický pro klienta, kusy, které jsou malé a používají se pouze pro každého klienta.

  • v kódu hlavní jednotky použijte #ifdef a #include a udělejte něco podobného

 # ifdef KLIENT = CLIENTA 
 # include "frangulator_client_a.c" 
 # endif 

Použijte to jako vzor znovu a znovu ve všech kódových jednotkách, které vyžadují přizpůsobení specifické pro klienta.

To je VELMI ošklivé a vede k dalším problémům, ale je to také jednoduché a poměrně snadno můžete vzájemně porovnávat soubory specifické pro klienta.

To také znamená, že všechny části specifické pro klienta jsou vždy jasně viditelné (každý ve vlastním souboru) a existuje jasný vztah mezi hlavním souborem kódu a částí souboru specifickou pro klienta.

Máte-li opravdu chytrý, můžete nastavit makefiles k vytvoření správné definice klienta, takže něco jako:

udělat klientu

bude stavět pro client_a a "make clientb" bude pro client_b a tak dále.

(a „značka“ bez poskytnutého cíle může vydat varování nebo popis použití.)

Podobné myšlenky jsem už dříve použil, nastavení trvá nějakou dobu, ale může to být velmi efektivní. V mém případě jeden zdrojový strom postavil asi 120 různých produktů.

1
quickly_now

Pomocí SCM byste mohli udržovat pobočky. Udržujte hlavní větev nedotčené/čisté od vlastního kódu klienta. Proveďte hlavní vývoj v této oblasti. Pro každou přizpůsobenou verzi aplikace udržujte samostatné větve. Jakýkoli dobrý nástroj SCM bude opravdu slučitelný se slučováním poboček (na mysl přijde Git). Jakékoli aktualizace v hlavní větvi by měly být sloučeny do přizpůsobených větví, ale kód specifický pro klienta může zůstat ve své vlastní větvi.


Ačkoli je to možné, zkuste systém navrhnout modulárním a konfigurovatelným způsobem. Nevýhodou těchto vlastních větví může být to, že se pohybuje příliš daleko od jádra/hlavní jednotky.

1
Htbaa

V gitu, jak bych to udělal, je mít hlavní větev se všemi běžnými kódy a větve pro každého klienta. Kdykoli je provedena změna základního kódu, stačí přeformátovat všechny větve specifické pro klienta v horní části masteru, takže máte sadu pohyblivých oprav pro klienty, které jsou aplikovány na aktuální základní linii.

Kdykoli provádíte změnu pro klienta a všimnete si chyby, která by měla být zahrnuta v jiných větvích, můžete ji vybrat buď do masteru, nebo do ostatních větví, které potřebují opravu (i když různé pobočky klienta sdílejí kód) , pravděpodobně byste je měli oba odbočit od společné větve od mistra).

0
Cercerilla