it-swarm.asia

Birden çok istemci için aynı yazılımın farklı, özelleştirilmiş sürümlerini koruma

farklı ihtiyaçları olan birden fazla müşterimiz var. Yazılımımız bir dereceye kadar modülerleştirilmesine rağmen, her modülün iş mantığını burada ve her müşteri için biraz ayarlamamız gerektiğinden neredeyse kesindir. Değişiklikler muhtemelen modülü her müşteri için ayrı bir (fiziksel) modüle bölmek için çok küçük, yapı ile ilgili sorunlar, bağlantı kaosundan korkuyorum. Ancak, bu değişiklikler çok büyük ve bazı yapılandırma dosyalarındaki anahtarlarla yapılandırmak için çok fazla, çünkü bu dağıtım sırasında sorunlara ve özellikle de tamircilik tipi yöneticilerde çok fazla destek sorununa yol açacaktır.

Değişikliklerin söz konusu tek fiziksel modülün özel bir sürümünde yer aldığı, her istemci için bir tane olmak üzere birden çok derleme oluşturmasını istiyorum. Bazı sorularım var:

Derleme sisteminin birden çok derleme oluşturmasına izin verir misiniz? Farklı özelleştirmeleri özellikle svn kaynak kontrolünde nasıl saklamalıyım?

48
Falcon

İhtiyacınız olan şey özellik dallanması - kod organizasyonu. Özel senaryoda buna İstemciye özgü gövde dallaması çağrılmalıdır çünkü yeni şeyler geliştirirken (veya hataları çözerken büyük olasılıkla özellik dallamasını da kullanacaksınız) ).

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

Fikir, yeni özelliklerin şubelerinin birleştiği bir kod gövdesine sahip olmaktır. Yani istemciye özgü olmayan tüm özellikler.

Daha sonra, aynı özelliklerin dallarını gerektiği gibi birleştirdiğiniz müşteriye özel şubeleriniz de vardır (eğer isterseniz kiraz toplama).

Bu istemci dalları, geçici veya kısa ömürlü olmasalar da özellik dallarına benzer. Daha uzun bir süre korunurlar ve esas olarak sadece birleştirilirler. Mümkün olduğu kadar az müşteriye özel özellik dalı geliştirilmesi gerekir.

Müşteriye özgü dallar, gövdeye paralel dallardır ve gövdenin kendisi kadar aktiftirler ve hiçbir yerde birleştirilmezler.

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

Bunu SCM şubeleriyle yapmayın. Ortak kodu, bir kütüphane veya proje iskeleti artefaktı üreten ayrı bir proje haline getirin. Her müşteri projesi, ortak bir projeye bağımlılık olarak bağlı olan ayrı bir projedir.

Ortak temel uygulamanız Spring gibi bir bağımlılık enjeksiyon çerçevesi kullanıyorsa, en kolayıdır, böylece özel özellikler gerektiğinden her müşteri projesinde farklı nesne varyantlarını kolayca enjekte edebilirsiniz. Zaten bir DI çerçeveniz olmasa bile, bir tane eklemek ve bu şekilde yapmak en az acı verici seçiminiz olabilir.

39
Alb

Tüm istemciler için yazılımı tek bir şubede saklayın. Farklı müşteriler için yapılan değişikliklerin birbirinden ayrılmasına gerek yoktur. En önemlisi, yazılımınızın tüm istemciler için en iyi kalitede olmasını isteyeceksiniz ve çekirdek altyapınızdaki hata düzeltmesi, gereksiz birleştirme yükü olmadan herkesi etkilemeli ve bu da daha fazla hataya neden olabilir.

Ortak kodu modüle edin ve farklı dosyalarda farklı olan kodu uygulayın veya farklı tanımlarla koruyun. Derleme sisteminizin her istemci için belirli hedefleri olmasını sağlayın, her hedef yalnızca bir istemciyle ilgili kod içeren bir sürüm derler. Örneğin, kodunuz C ise, farklı istemciler için özellikleri "#ifdef "veya dilinizin yapılandırma yapılandırması yönetimi için sahip olduğu herhangi bir mekanizma ve müşterinin ödediği özellik miktarına karşılık gelen bir dizi tanım hazırlayın.

ifdefs'den hoşlanmıyorsanız, "arabirimleri ve uygulamaları", "işlevleri", "nesne dosyalarını" veya dilinizin farklı şeyleri tek bir yerde saklamak için sağladığı araçları kullanın.

Kaynakları istemcilerinize dağıtırsanız, derleme komut dosyalarınızın özel "kaynak dağıtım hedefleri" olmasını sağlamak en iyisidir. Böyle bir hedefi çağırdıktan sonra, yazılımınızın sources özel bir sürümünü oluşturur, onları ayrı bir klasöre kopyalar, böylece onları gönderebilir ve derlemezsiniz.

13
P Shved

Pek çok kişinin belirttiği gibi: kodunuzu doğru şekilde faktörlendirin ve ortak koda göre özelleştirin - bu, sürdürülebilirliği önemli ölçüde artıracaktır. Nesne yönelimli bir dil/sistem kullansanız da kullanmasanız da, bu mümkündür (C'de yapmak gerçekten nesne odaklı bir şeyden biraz daha zordur). Bu, kalıtım ve kapsüllemenin çözülmesine yardımcı olan problem türüdür!

8
Michael Trausch

Çok Dikkatli

Feature Branching bir seçenektir ancak biraz ağır buluyorum. Ayrıca, kontrol altında tutulmazsa uygulamanızın çatallaşmasına yol açabilecek derin değişiklikleri kolaylaştırır. İdeal olarak, çekirdek kod tabanınızı olabildiğince yaygın ve genel tutmak için özelleştirmeleri mümkün olduğunca yukarı itmek istersiniz.

Ağır modifikasyonlar ve yeniden faktoringler olmadan kod tabanınız için geçerli olup olmadığını bilmiyorum ama ben bunu nasıl yapacağım. Temel işlevselliğin aynı olduğu benzer bir projem vardı, ancak her müşterinin çok özel bir özellik setine ihtiyacı vardı. Daha sonra yapılandırma (à la IoC) ile birleştirdiğim bir dizi modül ve kap oluşturdum.

daha sonra her müşteri için temel olarak yapılandırmaları ve yapı komut dosyasını içeren bir proje oluşturdum. Bazen bu istemci için özel olarak yapılmış bazı bileşenleri de yerleştiriyorum. Ancak bu nadirdir ve mümkün olduğunda daha genel bir formda yapmaya ve diğer projelerin bunları kullanabilmesi için aşağı itmeye çalışıyorum.

Sonuç olarak, ihtiyaç duyduğum özelleştirme düzeyini aldım, özelleştirilmiş kurulum komut dosyaları aldım, böylece müşteri sitesine ulaştığımda sistemi her zaman tweek ediyor gibi görünmüyorum ve çok önemli bir bonus olarak aldım direk olarak yapıya bağlanmış regresyon testleri oluşturabilme. Bu şekilde her zaman müşteriye özgü bir hata alıyorum Sistemin dağıtıldığını iddia edecek bir test yazabilirim ve böylece bu seviyede bile TDD yapabilirim.

kısacası:

  1. Düz proje yapısına sahip ağır modüler sistem.
  2. Her yapılandırma profili için bir proje oluşturun (müşteri birden fazla profili paylaşabilse de)
  3. Gerekli işlevsellik setlerini farklı bir ürün olarak birleştirin ve bu şekilde kullanın.

Düzgün yapılırsa, ürün Montajınız birkaç yapılandırma dosyası dışında tümünü içermelidir.

Bunu bir süre kullandıktan sonra, en çok kullanılan veya temel sistemleri bir çekirdek birim olarak birleştiren ve bu meta paketi müşteri montajları için kullanan meta-paketler oluşturdum. Birkaç yıl sonra, müşteri çözümleri oluşturmak için çok hızlı bir şekilde bir araya getirebileceğim büyük bir araç kutusuna sahip oldum. Şu anda Spring Roo 'a bakıyorum ve bir gün daha ilk etapta müşteriyle sistemin ilk taslağını oluşturabileceğimi umarak fikri biraz daha zorlayamıyorum. sanırım buna Kullanıcı Odaklı Geliştirme ;-) diyebilirsiniz.

Umarım bu yardımcı oldu

5
Newtopian

Değişiklikler muhtemelen modülü her müşteri için ayrı bir (fiziksel) modüle bölmek için çok küçük, yapı ile ilgili sorunlar, bağlantı kaosundan korkuyorum.

IMO, çok küçük olamazlar. Mümkünse, hemen hemen her yerde strateji desenini kullanarak istemciye özgü kodu dışarı faktör olurdu. Bu, dallanması gereken kod miktarını azaltır ve genel kodun tüm istemciler için senkronize olmasını sağlamak için gereken birleştirmeyi azaltır. Ayrıca testi basitleştirecektir ... varsayılan kodu kullanarak genel kodu test edebilir ve istemciye özgü sınıfları ayrı ayrı test edebilirsiniz.

Modülleriniz, modül A'da X1 ilkesinin kullanılması, modül B'de politika X2 kullanılmasını gerektirecek şekilde kodlandıysa, X1 ve X2'nin tek bir politika sınıfında birleştirilebilmesi için yeniden düzenleme düşünün.

3
kevin cline

Düz C yazıyorsanız, işte bunu yapmanın oldukça çirkin bir yolu var.

  • Ortak kod (örn. "Frangulator.c" birimi)

  • istemciye özgü kod, küçük olan ve yalnızca her istemci için kullanılan parçalar.

  • ana birim kodunda, #ifdef ve #include komutlarını kullanarak

 # ifdef İSTEMCİ = CLIENTA 
 # "frangulator_client_a.c" 
 # endif 

Bunu, istemciye özgü özelleştirme gerektiren tüm kod birimlerinde tekrar tekrar bir desen olarak kullanın.

Bu ÇOK çirkin ve diğer bazı sorunlara yol açar, ancak aynı zamanda basittir ve istemciye özgü dosyaları diğerine karşı kolayca karşılaştırabilirsiniz.

Ayrıca, istemciye özgü tüm parçaların her zaman açıkça görülebilir (her biri kendi dosyasında) ve ana kod dosyası ile dosyanın istemciye özgü kısmı arasında açık bir ilişki olduğu anlamına gelir.

Gerçekten akıllı olursanız, doğru istemci tanımını oluşturmak için makefiles kurabilirsiniz, böylece:

clienta yap

client_a için oluşturulacak ve "make clientb" client_b için yapacaktır vb.

(ve sağlanan hedefi olmayan "yap" uyarısı veya kullanım açıklaması yayınlayabilir.)

Daha önce benzer bir fikir kullandım, kurulması biraz zaman alıyor ama çok etkili olabilir. Benim durumumda bir kaynak ağaç yaklaşık 120 farklı ürün üretti.

1
quickly_now

SCM'nizi şubeleri korumak için kullanabilirsiniz. Ana dalı istemci özel kodundan bozulmamış/temiz tutun. Bu dalda ana gelişme yapın. Uygulamanın her özelleştirilmiş sürümü için ayrı dalları korumak. İyi bir SCM aracı, şubeleri birleştirmekle gerçekten iyi sonuç verecektir (Git akla geliyor). Ana daldaki tüm güncellemeler, özelleştirilmiş dallarla birleştirilmelidir, ancak istemciye özgü kod kendi dalında kalabilir.


Yine de, mümkünse, sistemi modüler ve yapılandırılabilir bir şekilde tasarlamaya çalışın. Bu özel dalların dezavantajı, çekirdek/ustadan çok uzakta hareket etmesi olabilir.

1
Htbaa

Git'te bunu yapmamın yolu, her müşteri için ortak kodun ve dalların hepsine sahip bir ana şubeye sahip olmaktır. Çekirdek kodda her değişiklik yapıldığında, sadece istemciye özgü dalların tümünü master'ın üzerine yeniden birleştirin, böylece mevcut taban çizgisinin üstüne uygulanan istemciler için bir dizi hareketli düzeltme eki elde edersiniz.

Bir müşteri için bir değişiklik yaptığınızda ve diğer dallara dahil edilmesi gereken bir hata fark ettiğinizde, bunu ana ya da düzeltmeye ihtiyaç duyan diğer dallara alabilirsiniz (farklı müşteri şubelerinin kod paylaşmasına rağmen) , muhtemelen ikisinin de efendiden ortak bir dal koparması gerekir).

0
Cercerilla