Sabit kodlanmış değerleri ve savunma tasarımını YAGNI ile kaldırma


10

İlk olarak biraz arka plan. Yaş -> Ücret aramasını kodluyorum. 7 yaş aralığı vardır, bu nedenle arama tablosu 7 satırlı 3 sütundan (Kimden | Kime | Ücret). Değerler nadiren değişir - bunlar 3 yıl boyunca aynı kalan yasal oranlardır (birinci ve üçüncü sütunlar). Bu tabloyu sabit kodlamadan depolamanın en kolay yolunun, bir CSV içeren tek bir metin değeri olarak genel yapılandırma tablosundaki veritabanında olduğunu anladım (böylece "65,69,0.05,70,74,0.06" 65-69 ve 70-74 katmanları depolanır). Ayrıştırmak sonra kullanmak nispeten kolay.

Daha sonra bunu uygulamak için yeni bir tablo, etrafına sarmak için bir havuz, repo için veri katmanı testleri, CSV'yi masanın içine sürükleyen kodun etrafında birim testler ve aramanın etrafındaki testler oluşturmam gerektiğini fark ettim. Tüm bu çalışmaların tek yararı, arama tablosunu kodlamaktan kaçınmaktır.

Kullanıcılarla konuşurken (şu anda arama tablosunu doğrudan kullanan - basılı bir kopyaya bakarak) görüş hemen hemen "oranlar asla değişmez". Açıkçası bu aslında doğru değil - oranlar sadece üç yıl önce yaratıldı ve geçmişte "asla değişmeyen" şeylerin değişme alışkanlığı vardı - bu yüzden bunu savunmacı bir şekilde programlamak için kesinlikle arama tablosunu saklamamalıyım uygulama.

YAGNI diye düşündüğüm hariç . Uyguladığım özellik oranların değişeceğini belirtmiyor. Oranlar değişirse, bakım o kadar nadiren değişecek ve bakım bile dikkate alınmayacak ve özellik, oran değişikliği ile güncellenen uygulama arasında bir gecikme olursa herhangi bir şey etkilenecek kadar kritik değildir.

Ben arama zor kod eğer değer hiçbir şey kaybolmayacağına karar verdim ve ben bu özel özelliği benim yaklaşım hakkında çok endişe değilim. Sorum şu: Bir uzman olarak bu kararı doğru bir şekilde gerekçelendirdim mi? Sabit kodlama değerleri kötü bir tasarımdır, ancak değerlerin uygulamadan kaldırılması sorununa gitmek YAGNI ilkesini ihlal ediyor gibi görünmektedir.

DÜZENLEME Soruyu açıklığa kavuşturmak için gerçek uygulamadan endişe etmiyorum. Ya hızlı, kötü bir şey yapabileceğimden ve YAGNI diyerek bunu haklı çıkarabildiğimden ya da en iyi durumda bile sonuçta düşük faydaları olan daha savunmacı, yüksek çaba gerektiren bir yaklaşım benimseyebileceğimden endişeliyim. Profesyonel bir programcı olarak kusurlu olduğunu bildiğim bir tasarımı uygulama kararım basitçe bir maliyet / fayda analizine iniyor mu?

DÜZENLEME Bir bireyin tasarım tercihlerine geldiğini düşündüğüm için tüm cevaplar çok ilginç olsa da, en iyi cevapların soruda dikkate almadığım şeyleri ortaya çıkardıklarında @ Corbin ve @EZ Hart'ın olduğunu düşünüyorum:

  • veritabanına taşıyarak 'sabit kodlanmış değerleri doğru şekilde kaldırmanın' yanlış ikilemesine karşı sabit kodlama kullanarak 'YAGNI'yi etkili bir şekilde uygulamak'. Arama tablosunu uygulama yapılandırmasına koymanın üçüncü bir seçeneği vardı, bu da doğru şekilde ek yüke neden olmaz ve YAGNI'nin verimliliği olmadan. Genel olarak, ya / veya kararlarla sınırlı değiliz ve daha sonra bir maliyet / fayda kararına düşer.
  • kod üretimi, sabit kodlanmış değerleri veritabanına taşıma yükünü azaltabilir ve bir CSV'yi tabloya işleme konusundaki aşırı tasarlanmış kararımı da kaldıracak şekilde. Arama yöntemi için temel gereksinimler değişirse, bu potansiyel olarak oluşturulan kodla ilgili uzun vadeli bir bakım sorunu da ekler. Tüm bunlar sadece maliyet / fayda analizini etkiler ve muhtemelen otomasyona sahip olsaydım böyle bir şeyi kodlamayı bile düşünmezdim.

@ Corbin'in cevabını doğru olarak işaretliyorum çünkü geliştirme maliyeti varsayımlarımı değiştiriyor ve muhtemelen yakın gelecekte cephaneme bazı kod oluşturma araçları ekleyeceğim.


Oranlar değiştiğinde ve sahip olduğunuz tüm değerler sabit kodlanmış değerler ise, oranlar değiştiğinde geçmiş kayıt hesaplamalarını bozabilirsiniz (ve müşterinizin size ne söylediğine bakılmaksızın).
Andy

Yanıtlar:


6

Geliştirme sürecinizde bir kusur buldunuz. Doğru olanı yapmak bir acı olduğunda (tablo oluşturmak, repo, repo testleri, testleri düzleştirmek ...), geliştiriciler bunun etrafında bir yol bulacaklar. Bu genellikle yanlış bir şey yapmayı içerir. Bu durumda, uygulama verilerine uygulama mantığı olarak davranmanız caziptir. Yapma. Bunun yerine, geliştirme sürecinize yararlı otomasyonlar ekleyin. Biz hiç kimsenin yazmak istemediği sıkıcı, kaynak kodunu üretmek için CodeSmith'i kullanıyoruz . Bir tablo oluşturduktan sonra, CodeSmith'i çalıştırırız ve her biri için DAO'ları, DTO'ları ve birim testlerini oluşturur.

Kullandığınız teknolojilere bağlı olarak, benzer seçeneklere sahip olmalısınız. Birçok ORM aracı mevcut bir şemadan modeller oluşturur. Raylar geçişleri ters yönde çalışır - modellerden tablolar. Dinamik dillerde meta-programlama özellikle kazan plakası kodunu ortadan kaldırmada güçlüdür. Karmaşık bir çok katmanlı uygulamanız varsa, ihtiyacınız olan her şeyi oluşturmak için biraz daha fazla çalışmanız gerekecek, ancak buna değer. "Vay canına, bu boyunda bir acı" hissine izin vermeyin, doğru şeyi yapmanıza engel olun.

Oh, ve verilerinizi ek işleme (CSV) gerektiren bir formatta saklamayın. Bu sadece dikkatinizi ve testinizi gerektiren ekstra adımlar ekler.


Bir Rails geçişinin modellerden tablolar oluşturduğunu söyleyemem ... Rails geçişleri tablolardaki değişiklikleri açıklar. Bir geçişin yürütülmesi veritabanını değiştirir. Tablo yapısıyla eşleşen model özellikleri çalışma zamanında oluşturulur.
kevin cline

Bu beni ilgilendiriyor, ilk eforun bu bölümlerini otomatikleştirmeyi düşünmemiştim. Bu otomasyona sahip olmak, zaman kazanmak için CSV kullanmak yerine tam bir tablo oluşturabileceğim anlamına gelir. Ne hakkında endişe oluşturulan kodun uzun vadeli bakım. Açık bir şekilde oluşturarak, arama yapma yönteminin asla değişmeyeceği konusunda erken bir varsayım yaptım. Sanırım bunun bir olasılık olup olmadığını, maliyetin / yararın bir parçası olarak dikkate almalıyım ve kazan levhasının maliyetini düşürmeliyim. +1
Rebecca Scott

Soru, "Müşterim değişmeyeceklerini söylediğinde değerleri kodlamam gerekir mi?" ve cevabınız "hayır, ve aslında soruna bir ORM atmalısınız." Katılmıyorum. OP'nin kodlamayı önlemek için daha basit seçenekler vardır. Açıkça gereksiz olarak belirlenen şeyleri desteklemek için mimariye büyük eklemeler yapmak etik değildir. Birçok geliştiricinin böyle şeyler yapmaya yatkın olması talihsiz bir durumdur. Ve şunu söylemeliyim ki, “duyguya izin vermeyin”, vay be, bu boyundaki bir acıdır 'doğru şeyi yapmanıza engel olunmaz' önerisiyle% 100 katılmıyorum. Bu duygular önemli!
user1172763

10

@ Thorbjørn Ravn Andersen'in cevabını kapatmak ve genişletmek için: Hesaplamayı / aramayı tek bir yerde tutmak iyi bir başlangıçtır.

Savunma ve YAGNI arasındaki düşünce süreciniz yaygın bir sorundur. Bu durumda, iki şey daha bilgilendirilmesini öneririm.

İlk olarak - kullanıcı gereksinimi nasıl sunuldu? Oranların düzenlenebilirliğini belirlediler mi? Değilse, eklenen karmaşıklık faturalayabileceğiniz bir şeyin parçası mıdır? (ya da personel iseniz, bunun yerine başka bir iş yapmak için zaman harcayabilirsiniz?) Öyleyse, o zaman kesinlikle devam edin ve makul ne istediğini teslim.

İkincisi ve belki de daha önemlisi, sadece düzenlenebilirliğin yasal bir değişiklik karşısında gerçek bir gereksinimi yerine getirmesi olası değildir. Oranlar değişirse ve ne zaman değişirse, bir kesinti tarihi ve gerçekleşmesi gereken işlem öncesi ve sonrası olabilir. Ayrıca, aynı arabirim daha sonra herhangi bir geri tarihli talep işleme yapmak zorundaysa, o zaman gerçek tarih yerine girişin yürürlük tarihine göre doğru oranın aranması gerekebilir.

Kısacası, gerçek bir düzenlenebilir gereksinimin oldukça karmaşık olabileceğine dikkat çekiyorum , bu yüzden ete gelmedikçe veya etmedikçe, basit muhtemelen daha iyidir.

İyi şanslar


1
İkinci noktanız için +1. Gelecekte yasama organlarının neler yapabileceğini tahmin etmeye çalışmıyorum.
David Thornley

Bir kütüphane işlevinde yapın. Yalnızca bir kullanıcının olması sorun yaratmaz. Gereksinimler ne zaman değişirse değişecek bir yeriniz vardır. (Belirli bir tarihten itibaren değer için arama yapmak için bir işlev eklemeniz gerekebilir.)
BillThor

En iyi ve en eksiksiz cevap, +1
Andy

7

Gerçek aramayı bir kütüphane işlevi haline getirin. Daha sonra kaynak havuzunuzda bu aramayı kullanarak tüm kodu görebilirsiniz , böylece oranlar değiştiğinde hangi programların yükseltilmesi gerektiğini bilirsiniz.


Arama yalnızca PensionRateLookupdaha sonra küresel olarak kullanılan tek bir yerde ( belki sınıf gibi bir yerde ) uygulanacaktır. Uygulama dışında depolanmış veya sabit kodlanmış olsun, bu şekilde yalnızca PensionRateLookupsınıfın uygulanmasının sürdürülmesi gerekir. Benim sorunum, arama tablosunun zor kodlanmasının kabul edilebilir olduğu sonucuna varmak için YAGNI'yi nasıl kullandığımdır.
Rebecca Scott

Yine de cevabınız için teşekkürler. Arama uygulamasını tek bir yerde tutmak kesinlikle iyi bir tasarımdır.
Rebecca Scott

YAGNI sadece oranlar değiştiğinde yeni ikili dosyalar gönderebiliyorsanız geçerlidir. Yapılandırmayı değiştiremez, ancak değiştirebiliyorsanız, başlangıçta geçerli metin temsiliyle varsayılan olarak okunan bir yapılandırma değeri yapın.

Genellikle haftalık olarak yeni bir sürüm gönderiyorum, aslında aramayı güncellemek sorun değil. İstemci yapılandırmasına koymak, istemci yapılandırmasını yeni bir ikili dosyayla değiştiremediğim için aslında daha kötüdür. Gördüğüm gibi alternatif veritabanına koyarak çok çaba anlamına geliyor.
Rebecca Scott

O zaman sorun nedir? Ücretler değiştiğinde, kodu güncelleyip tüm müşterilere gönderiliyor musunuz?

2

Sorunuzu doğru anladım mı bakayım. Bir özelliği uygulamak için 2 seçeneğiniz vardır: ya bir değeri sabit kodluyorsunuz ve özelliğinizin uygulanması kolaydır (btu sabit kod bölümünü beğenmezsiniz) ya da yapılan birçok şeyi "yeniden yapmak" için çok büyük bir çabanız vardır böylece size özel bir özellik geliştirebileceksiniz. Bu doğru mu?

Aklıma ilk gelen şey, "İyi uygulamaları bilmekle ilgili en önemli şey, onlarsız ne zaman daha iyi olduğunuzu bilmektir."

Bu durumda, çaba çok yüksektir, bu yüzden temiz bir şekilde yapabilirsiniz, bu değişikliğin teminat etkisi olasılığı yüksektir ve alacağınız getiri küçüktür (açıkladığınız gibi, muhtemelen değişiklik).

Sabit kod yaklaşımını kullanırdım (ancak gelecekte esnek olmaya hazır olun) ve gelecekte bu oranın değişmesi durumunda, kodun tüm bu kötü tasarım bölümünü yeniden düzenleme fırsatını kullanın. Böylece zaman ve maliyet doğru bir şekilde tahmin edilebilir ve sabit kodlu değerinizi değiştirmenin maliyeti minimum olacaktır.

Bu benim yaklaşımım :)


Teşekkürler @Oscar. Bunun teknik kısmı def. doğru. Ve sadece gerektiğinde yeniden düzenleme yaparak soruna nasıl yaklaşacağınıza katılıyorum. Yani bir profesyonel olarak tasarım ilkelerimizi sadece maliyet / faydaya dayanarak seçebileceğimizi ve seçmemiz gerektiğini mi söylüyorsunuz? Mantıklı.
Rebecca Scott

@Ben Scott: Bir şey değil :). Evet, benim görüşüme göre, tasarım ilkeleri güzel göründükleri için değil, kod "temizlik", esneklik, sağlamlık, vb. ? 2- Kısıtlamalarım (zaman, teknik vb.) Uygulamamı sağlıyor mu? Bu genellikle tasarım ilkemi seçmeme neden oluyor. Aşırı mühendislik de kötü;) ps: ilginç bir cevap olduğunu düşünüyorsanız, lütfen oy verin, böylece diğer insanlar da daha yüksek bir olasılıkla okur. Teşekkürler! :)
JSBach


2

Bu, değişene kadar "değişmeyecek" bir öğedir. Değişmesi kaçınılmazdır, ancak bu süre biraz uzakta olabilir.

Gerekçeniz doğrudur. Şu anda, müşteri bu oranları kolayca değiştirme yeteneğini istemedi. Bu nedenle, YAGNI.

Bununla birlikte, istemediğiniz, oranlarınıza erişen ve kod tabanına dağılmış sonuçları yorumlayan koddur. İyi OO tasarımı, bir sınıftaki oranlarınızın dahili temsilini kapsüllemenizi ve yalnızca verileri kullanmak için gereken bir veya iki yöntemi ortaya çıkarmanızı sağlar.

Kopyalama ve yapıştırma hatalarını önlemek için bu kapsüllemeye ihtiyacınız olacak veya dahili gösterimde bir değişiklik yapmanız gerektiğinde oranları kullanan tüm kodlarda yeniden düzenleme yapmak zorunda kalacaksınız. Bu ilk önlemi aldığınızda, daha karmaşık yaklaşım basit bir takas olabilir ve daha özellikli sürümün yerini alabilir.

Ayrıca, mevcut tasarımın istemciye sınırlandırılmasını çağırın. Onlara, programı korumak amacıyla değerleri sabit olarak kodladığınızı söyleyin - bu, bunları güncellemek için bir kodlama değişikliği gerektirir. Bu şekilde, yeni mevzuat nedeniyle bekleyen oran değişikliklerinin farkına vardıklarında, arama tablosunu güncellemeyi veya o sırada daha karmaşık değişiklikleri gerçekleştirmeyi seçebilirler. Ama bu kararı kucağına koy.


Teşekkürler @berin, soruda SRP'den bahsetmedim ama plandaydı. Sorunun sahipliğini müşteriye geri vermek iyi bir nokta.
Rebecca Scott

Gelecekte işler ters gittiğinde suçu atamak bana profesyonel gelmiyor.
Andy

@Andy, bunun hangi kısmı suçluyor? Tasarım sınırlamalarını müşteriye sunmak, onlara karmaşık işi şimdi önceliklendirme ve masadaki diğer şeyleri alma, son tarihi geri çekme veya masadaki diğer şeyler onlar için daha önemli olduğu için sınırlı tasarımı şimdi kabul etme fırsatı verir. Müşterinize ürün seçimiyle güç veriyorsunuz. Müşterinizin, kendi çıkarları için yapmak istediğiniz seçimlerin risk / ödülünün farkında olması, projenin daha sorunsuz çalışmasını sağlayacaktır.
Berin Loritsch

@BerinLoritsch Ama bu özel tasarım kararı, "Bu sızdıran boruyu tıkamak için tesisatçı macunu kullanabilirim, bu en ucuz seçenek!" Oranlar değişecek. Bu bir verilen ve bir profesyonel izin vermeyen bir sistem kurmak için sorumsuz. Ve projenin maliyetinin büyük planında tasarruflar muhtemelen ihmal edilebilir. Verileri bir tabloya koyun; arama verilerini alan kod biraz farklıdır, mantık hangi oranın kullanılacağını her iki şekilde de belirler. Diğer tek karar tarihi veriler nasıl
Andy

oranlar değişir; bu genellikle oranın yalnızca ilgili kayda kopyalanmasıyla gerçekleştirilir. Bu noktada yönetici ekranına gerek yoktur, sistem daha sonra oranlar değiştiğinde işleyebilir ve bunları değiştirmek basit bir komut dosyası olacaktır. Bunların hiçbiri birkaç saatten fazla olmamalıdır, ancak bodrumun gelecek yıl macun başarısız olduğunda taşmasını önleyecektir.
Andy

2

Farkı bölün ve hız verilerini bir yapılandırma ayarına yerleştirin. Zaten sahip olduğunuz CSV biçimini kullanabilirsiniz, gereksiz veritabanı ek yükünü önlersiniz ve değişiklik gerekirse, müşterinin yeniden derlemek / yeniden yüklemek zorunda kalmadan ve karışıklık olmadan yapabilmesi gereken bir değişiklik olacaktır. veritabanında - sadece yapılandırma dosyasını düzenleyebilirler.

Genellikle iki uç arasında bir seçeneğe bakarken (YAGNI ile sabit kodlama dinamik verilerini ihlal edin), en iyi cevap ortada bir yerdedir. Yanlış ikiliklere dikkat edin.

Bu, tüm yapılandırmanızın dosyalarda olduğunu varsayar; kayıt defteri gibi zor bir yerde, muhtemelen bu tavsiyeyi dikkate almamalısınız :)


Bir yapılandırma ayarında sahip düşündüm ama bir CSV dize düzenleme kadar çok teknik olmadığı için bir kenara koyun, bu yüzden N kullanıcıları için yapılandırmayı güncelleyen biri olacak (tüm BT desteğini yaptığım gibi) org da), çaba açısından, tek bir yerden yönetebileceğim veritabanına almak için açık işi yapmak daha kolay olurdu. Sanırım bu bir düşünce olmasaydı (kullanıcılar kendi yapılandırmalarını yönetebilseydi) bu problemi yaşamazdım. Çok iyi bir nokta, teşekkür ederim.
Rebecca Scott

Bunu merkezi mantığın diğer önerileriyle birleştirdiyseniz, bu harika bir cevaptır. Yapılandırma yoluyla değiştirilmesine izin veren bir şekilde koymak yerine aramayı gerçekten zorlaştırmak saf kötülüktür. Başka bir geliştirici karşılaştığında bunun için senden nefret ederler. Bir adam geliştirme mağazası bile bir otobüsün çarpması durumunda ne olacağını düşünmeli ve bir sonraki geliştiricinin tam bir yazılım sürümü olmadan değerleri değiştirmesini kolaylaştırmalıdır. Sadece istemciden nefret ediyorsanız ve diğer tüm geliştiricilerden nefret ediyorsanız, hardcore yapmalısınız. Temelde asla.
simbo1905

2

Bu tabloyu sabit kodlamadan saklamanın en kolay yolunun, bir CSV içeren tek bir metin değeri olarak genel yapılandırma tablosundaki veritabanında olduğunu anladım (böylece "65,69,0.05,70,74,0.06" 65-69 ve 70-74 katmanları depolanacaktı.

Sadece bir DB Tablosu oluşturduk. (Bir masanın tamamını bir dosyada saklamayı düşündüğünüzde, delirdiniz mi?)

Tablo 3 DEĞİL 3 alana ihtiyaç duyar. Yaş ve Oran. Bu sonraki satır üst değeri içerir! Bilmeden bile normalleştiriyorsun!

İşte Sql 67 yaşında birisinin oranını almak için.

Select * from RateTable where Age in (Select max(age) from RateTable where age <=67) 

Kapsam dışı olduğu için bir bakım ekranı yapmak için uğraşmayın. Daha sonra isterse bir değişiklik isteği yayınlayın ve yapın.

DÜZENLEME: Diğerlerinin söylediği gibi, tüm Rate yapısının değişmesi durumunda, kodu merkezileştirir .


Merhaba @Morons, cevabınız için teşekkürler. Tablonun aslında 3 sütuna ihtiyacı vardır. Yaş aralığı , min yaş - maks. Yaş arasında tek bir orandır (65-69 yaş arası% 5'tir). Ve sadece sınırlı bir amaç için az miktarda veri saklıyorum, bu yüzden yapıyı yeniden varsaymak ve özel bir tablo yerine bir CSV'ye gitmek yanlış olabilir mi? Muhtemelen bir satır ayırıcı eklemek ve satır ve sonra sütun bölünmüş ve gerekli alanlara sütunları çekmek istiyorum. Bu her zaman yazıldığından çok daha fazla okunacaktır, bu yüzden tam bir masa için çok endişelenmiyorum.
Rebecca Scott

Sonraki Satır Aralığın üst değerini içerir ... Bu verilerin kopyalanmasıdır. <69 ve> 7 demek aynı şeydir. Her iki değere sahip olmanın tek nedeni, aralıkta Delikler olup olmadığıdır. ... bir masa kullanmayı söylüyorum çünkü bu daha kolay (ve daha iyi bir tasarım). Neden bir csv bir tabloya saklamak herhangi bir zaman veya çaba kurtaracağını düşünüyorum anlamıyorum, hala sadece bu dize almak için bir DB çağrısı gerekir, sonra ayrıştırmak zorunda. Yukarıda gösterdiğim gibi, tek bir DB çağrısı ile oranı alabilirsiniz.
Moronlar

Ah doğru. Masanın kendisini kaynak materyale benzer tutuyordum ... ve cevabınızdaki yaşın üst sınır olduğunu kaçırdım çünkü üzüntü verdiğim üzüntüleri yaşadım.
Rebecca Scott

1
"Bilmeden bile moral bozuyorsun!" - ilk başta bunun bir yazım hatası olduğunu düşündüm ve 'denormalizing' demek istediniz, ama ne kadar çok düşündüğümde o kadar doğru olabilirsiniz :)
EZ Hart

@ez hart LOL doğru.
Rebecca Scott

1

Verilen cevapların çoğuna katılıyorum. Ayrıca, uygulamanın geri kalanıyla tutarlılığın önemli olduğunu da ekleyeceğim. Kodda sabit kodlanmış değerlere sahip tek yer bu ise, muhtemelen bakıcıları şaşırtacaktır. Bu, özellikle büyük, kararlı bir kod tabanı ise doğrudur. Sizin tarafınızdan tutulan küçük bir programsa, karar daha az önemlidir.

Kod çoğaltma için başparmak kuralının iki ve sadece iki kez olduğunu söyleyerek iyi bilinen bir çevik / OOP adamı (Dave Thomas veya Kent Beck veya birisi gibi) okurken uzak bir anı var: hayatınızda yalnızca iki kez yazabilirsiniz. Ama üçüncü kez ...

YAGNI'yi sorguladığınız için bu tam olarak soruyu ele almıyor, ancak bence çevik kuralların genel esnekliğini konuşuyor. Çevik olan nokta duruma uyum sağlamak ve ilerlemektir.


Teşekkürler @Dave, bu yararlı. Başlangıçtan tek bakıcıyım, ancak büyük, nispeten istikrarlı bir kod tabanı (binlerce dosya, 100'den fazla tablo vb.) Ve hala sürekli şaşırdım (ve dehşete düştüm). Tutarlılık kesinlikle ileriye dönük hedeflerimden biri.
Rebecca Scott

0

Bir fonksiyondaki sabit kod.

  • Değerler değiştiğinde müşteriyi tekrar faturalandırabilirsiniz
  • Değerler değiştiğinde, tablo biçiminin değişmesi ihtimali vardır, CSV yapmak zaman kaybeder
  • Uygulanması daha kolay, mevcut sözleşmeyle bütçede olma şansı daha yüksek
  • Güncellenmesi gerektiğinde kolayca bulabilir

Bu standart altı değeri yükleyeyim, bu yüzden bir yıl içinde kesinlikle kırıldığında tekrar iş alıyorum. Kulağa gölgeli geliyor, çünkü öyle.
Andy
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.