Kullanıcı Arabirimi sınıflarının bir komut satırı arayüzü ile değiştirilebileceğini düşünerek bir mimari tasarlamak iyi bir fikir midir?


92

Kod Tamamlama sayfa 25'te, normal kullanıcı arayüzü sınıflarını bir komut satırı ile kolayca değiştirmenin iyi bir fikir olduğu söylenir.

Test etmenin avantajlarını bilerek, getirebilecekleri sorunlar ne olacak?

Bu ekstra iş gerçekten web ve mobil projeler için karşılığını alacak mı? Küçük ve orta ölçekli projelerden ne haber; aynı kurallar geçerli mi? Ya tasarımınızı daha karmaşık hale getirirse?


2
Perl'de MooseX :: Getopt ve Plack :: Handler :: CLI gibi araçlar tam da budur .
Ether

4
Programınızı ilk önce bir CLI ile oluşturursanız, kullanıcı arayüzü programın derinliklerine gömülmüş bir kullanıcı arayüzünden çok daha fazla esneklik vererek üzerine yerleştirilebilir. Bu web servisleri için aynıdır.
zzzzBov

28
Her zaman güçlü bir kelimedir.
Mark Canlas

8
Lütfen orijinal alıntıya dikkat edin: "Mimari, modüler hale getirilmeli, böylece programın işletme kurallarını ve çıktı bölümlerini etkilemeden yeni bir kullanıcı ara yüzü kullanılabilir. Örneğin, mimarinin kullanımı kolaylaştırabilir interaktif arayüz sınıfları grubu ve bir komut satırı sınıfları grubuna takın. " Bu yüzden CC, bir GUI'yi komut satırıyla değiştirmek için hazırlanmanız gerektiğini söylemiyor, sadece mimarinin kullanıcı arayüzünü değiştirmeyi kolaylaştırması gerektiğini söylüyor. GUI-> komut satırı olayı sadece bir örnektir.
sleske,

2
@Vandell Ben Kodun İkinci Baskısı var ve bu sayfa 25'te belirtilmemiştir. Hangi basıma başvuruyorsunuz?
JW01

Yanıtlar:


43

İşlevselliği farklı arayüzler altında tekrar kullanabilmek (örn. GUI vs CLI vs REST) ​​her zaman gerekli değildir, ancak başkaları ile etkileşime girmenin yeni yollarını bulduğu için bir sistem için serendipitous yeniden kullanımına sahip olmak ve bunları etkinleştirmek güzeldir .

Bunun ağırlıklandırılması gereken birkaç dezavantajı vardır:

  1. Ek soyutlama katmanları gerektirir (bazen katmanları bile). Bu katmanlara sahip olmak iyi bir mühendislik uygulaması olsa da, geliştirme için ek bir maliyete sahiptir, bunun diğer alanlarda çabayı azaltamayacağının anlaşılması (örn. Bakım, yeniden kullanım, test), bu yüzden biraz düşünmeye değer.
  2. Bir ortam için en uygun akış diğerleri için korkunç olabilir. İşlevsellik bir GUI'yi desteklemek üzere tasarlandıysa , web için çok konuşkan olabilir . Tüm işlevsellikler her ortamda değerli değildir.
  3. Servisler ve kullanıcı arayüzü arasında genel bir dönüştürücü tanımlamaya çalışırken bir tuzak vardır, böylece servis sözleşmesini tanımlayabilir ve tüm ortamlar için kullanıcı arabirimini otomatik olarak (veya mümkün olduğunca) elde edebilir. Birçok proje, bu tür çerçeveler inşa etmek ve ihtiyaçlar değiştikçe mümkün olan her özelleştirmeyi eklemek için çok çaba harcadı.

Bunu söyledikten sonra tecrübelerime göre bu tür katmanları uygulamak her zaman çaba harcamaktan sona erdi. Birkaç vakada, sistemleri zamanında dağıtmayı başardım çünkü son kullanma tarihinden birkaç hafta önce medyayı (örneğin, Web Hizmetleri entegrasyonundan kullanıcı arayüzüne) değiştirmek zorunda kaldık.


2
Diğer yorumlar belirtildiği gibi, kod uyumunu arttırmalı ve eşleşmeyi azaltmalıdır. Bunların her ikisi de kodunuzu daha basit ve test etmesi daha kolay hale getirmelidir. Akış bir GUI konseptidir ve genellikle başka işlevlerde bulunmamalıdır.
BillThor

Bundan henüz söz edilmediğine inanamıyorum, ancak Model-View-Controller mimarisinin özü bu. Mesele, @BillThor'un söylediği gibi kuplajı azaltmak için, görüşlerini ve kontrol cihazlarını istediği zaman değiştirebilmektir. Bu MVC için en iyi kullanım şeklidir.
Rudolf Olah

110

Tamamen test etmenin yanı sıra, bu yaklaşımın bariz avantajı, projenizi otomatikleştirilebilir ve yazılabilir hale getirmesidir . Bir programa komut satırı komutları gönderebilirsem, karmaşık işleri gerçekleştirmek için bir komut dosyası yazabilirim, aynı şeyi GUI'de otomatikleştirmek için bir makro oluşturabileceğimden daha kolay (ve daha güvenilir!).

Bunun gerçekten de yapmaya değip değmeyeceği elbette, tamamen programınızı otomatikleştirmek isteyecek çok sayıda kullanıcınızın olup olmadığına bağlıdır.


12
Birçok uygulama komut dosyası için bir eklenti modeli kullanır. Genellikle nesne modeli ortaya çıkar ve scriptleri yazmak için python benzeri bir dil kullanılır. Komut satırı parametrelerinin önemsiz olmayan bir uygulama için çalışacağını sanmıyorum.
softveda

Diğer bir fayda keşfedilebilirlik olabilir. Sublime Text'in Ctrl-Shift-P özelliği buna harika bir örnektir. İstediğim bazı gizli işlevler varsa, menüler arasında arama yapmak yerine, çağrılacağını düşündüğüm şeyi yazdım, komutu görebiliyorum (ve kısayolu) ve hemen uygulayabiliyorum.
Adam Iley

Açık kaynaklı, Java tabanlı bir LDAP sunucusu olan OpenDJ buna harika bir örnektir: GUI'de yaptığınız her bir değişiklik için komut satırı onay iletişim kutusunda mevcuttur.
Franck,

1
@ Marnixv.R .: hareketler yalnızca bir komutla belirtilebilecek bazı eylemleri gerçekleştirmenin uygun bir yoludur, örneğin '35.73N 118.23W'da yakınlaştırın. Bir çizim komut olarak girilebilir, ancak uygunsuz olabilir. Yine de, elverişli bir şekilde komut dosyası oluşturulabilir bir arayüzde harika bir yardımcı program olduğunu ve bir tane oluşturmak için çok az emek harcandığını düşünüyorum.
kevin cline

7
+1: Bir diğer önemli avantaj, kullanıcı işlemlerini kaydetmeyi kolaylaştırarak üretim sorunlarının çoğaltılmasını basitleştirmesidir.
kevin cline

81

Fazladan iş değil, sadece farklı iş. Doğru yaparsanız, sadece daha karmaşık hale getirmekle kalmaz, daha basit hale getirir, çünkü tasarımınızı ayırmaya zorlar. CLI'yi gerçekten uygulayıp uygulamadığınız, tasarımınızın bunu mümkün kılması için daha iyi olacaktır.


4
Birkaç tamamen yanlış ifadeler için -1. Elbette daha karmaşık hale getirecek. Sonuçta, ek bir gereklilik / özelliktir.
Boris Yankov

@ BorisYankov "karmaşık" yerine "karmaşık" anlamına geldiğini düşünüyorum - kulağa benzer geliyorlar ve anlamlarıyla örtüşüyorlar, bu yüzden arada sırada
kafa

43

Bahsedilmemiş görünen bir önemli avantaj, bunu yapabilmenin , kullanıcı arayüzünün temel kuraldan katı bir şekilde ayrılmasını zorunlu kılmasıdır . Bu temel avantajlarından biri, yani, öyle önemli ölçüde GUI değiştirmeniz gerekiyorsa (iOS OSX standartlarına standartları veya bir grafik motorunu demek) anlamına gelir ki bütün temeldeki kod bağımlı olmadığı için, değiştirmek gerekir Arayüzün düzeni. O olamaz imiş, komut satırı araçları işe yaramaz, çünkü olun.

Bunun dışında, testleri otomatikleştirebilmek kilit bir avantajdır.


Yanılıyorsam düzelt, ancak bir
GUI'den

5
Evet, ama tüm bu doğrulama, değişmeniz gerektiğini söylediğim iyi bir kullanıcı arayüzünün parçası. Kullanıcının hesabının şu anki durumunu, örneğin öğeleri arama algoritmasını, oyunun kendine özgü kurallarını vb. Saklayan arka uç kodu. Buradaki en önemli şey, fare / klavye tabanlı kullanıcı arabiriminden geçiş yapmak zorunda kalmam Bir oyun için dokunmatik ekran UI, hala savaş hesaplamalarını ve puanlamayı ele almak için aynı arka uç motorunu kullanabilmeliyim, bu yüzden aynı temel sistemi kullanan yeni olay işleyicileri yazmaya odaklanabiliyorum.
deworde

2
Bu hiçbir şekilde kolay btw, olay işleyicileri yazmaktan nefret ediyorum ve işletme kodundan çok daha fazla doğrulama kodu oluşturdum. (Sizinle açıkladığınız gibi birleştiği konusunda
hemfikir olmama rağmen

2
@ClickUpvote Bir dereceye kadar GUI'nizi nasıl uyguladığınıza bağlıdır. ValueChanged mesajlarını yalnızca bir destek sınıfına gönderen ve buna karşılık olarak ValueValid / ValueInvalid mesajlarını alan gerçekten ince bir GUI, OnTextboxChanged olaylarındaki tüm doğrulama işlemlerinin yerine geçmesi çok daha kolay olacaktır.
Dan Neely,

@ClickUpvote Katılıyorum, bu yüzden bozulmamayı sevdiğim bir şeye odaklanabilmek ya da tam dikkatimden nefret ettiğim bir şeye odaklanabilmek istiyorum.
deworde 11

17

Evet, neredeyse her zaman iyi bir fikir.

Bu yaklaşımı izlerseniz, büyük olasılıkla GUI ile aynı iş parçacığında ve bazı GUI işleyicilerinin arkasında bir iş mantığı ya da veri erişiminiz olmaz. Bu nedenle tek başına yatırım yapmaya değer.


2
Örneğin bir metin editörü yazıyorsanız, bunun avantajı ne olurdu?
nikie

5
@nikie Örneğin, WYSIWIG metin düzenleyicinizin görünümünü düz bir metin veya biçimlendirme tabanlı bir ön uçla değiştirebileceğinizden ve aynı bilgiyi temel alınan modele ilettiği sürece mevcut altyapınız çalışmaya devam edecektir.
deworde

5

Bence bu iyi bir fikir. Ek olarak, ikinci bir komut satırı ön ucu yazabilmek, sonuçta iş mantığının herhangi bir özel uygulama sunucusu mimarisine tamamen ayrıldığını kanıtlar.


5

Bunu yaparken gördüğüm tek tehlike kullanıcı arayüzünde belirli bir bölüme ulaşmak için kullanıcının normalde kullanıcı arayüzünün diğer bölümlerini geçmesi gerektiğidir.

Geliştiricinin doğrudan kullanıcı arayüzünü çalıştırabileceği yer. Bir geliştiricinin, ürünü gerçekten kullanmadan önce bir kullanıcının sorununu yeniden üretemediği durumlar gördüm.

Öyleyse testler yaparken de bunu hesaba katın.


3

Hayır. Berbat bir tavsiye.

Bu biraz yagni (Buna ihtiyacınız olmayacak).

Bir komut satırı arayüzünü göstermek, uygulamanızı ünite testini destekleyecek şekilde yapılandırmak veya SOLID'in herhangi bir bölümüne veya önerdiğim herhangi bir programlama uygulamasına uymakla aynı değildir.

Komut satırı arayüzüne uygun olmayan herhangi bir UI için işe yaramaz. MS Paint gerçekten basit bir uygulamadır, ancak herhangi bir durumda, onu bir komut satırından kontrol edebilmenin faydasını nasıl görürsünüz?

Komut dosyası uygulamanıza yardımcı olmaz. Aslında bu yönde herhangi bir ilerlemeyi engelleyecektir.

Tek olumlu şey, sayfa 25'te göründüğü için, en azından kitabın geri kalanının olabileceği konusunda bir uyarı alıyorsunuz, koklamak. Uzun zaman önce okudum ve hoşuma gitmedi, bu yüzden önyargılıyım.


1
Kabul edildi +100000000

4
Scriptable MSPaint aslında gerçekten yararlı sesler.
RoundTower

IMO en iyi cevap. '' YAGNI 'uygulamayın' 'mantrasını takip ettiğimden beri, gerçek işlere yoğunlaşarak daha fazla zamana sahibim ve daha çok denemeye bile zamanım var. Zekice davranmaya çalışmak, müşterinin çoğu zaman daha önce belirtilenden farklı bir uzantı istediğini, bu yüzden de gerekmeyen bir şeye zaman kaybetmediğini gösterdi.
başında

PSPaint + komut satırı arayüzü = AutoCAD
Vorac

-1 (yapabilirsem) "Bir CLI'yi ve bir GUI'yi uygulama" demediğini unutmayın; "CLI gibi alternatif bir UI uygulaması için hitap" diyor.
Mark Hurd,

2

Mason Wheeler'ın söylediklerine dayanarak, bir komut satırı üzerinden bir uygulama ile etkileşime girebilmek görevleri otomatikleştirmeyi çok kolaylaştırıyor.

Bu özellikle testlerde faydalıdır.

Pratik bir örnek vermek gerekirse, bir uygulama üzerinde otomatik testler yapmak istersem, uygulamayı otomatik olarak kurmak isteyebilirim. Bunu yapmak için, "myApplication.exe / silentinstall" adlı aşağıdaki parametreleri geçebilirim.

Bunu, bu komut satırı anahtarını belirttiğimde, GUI yükleyici olmadan arka planda sessizce bir yükleme yapılacağı şekilde programlayabilirim. Yükleyiciye herhangi bir giriş (yükleme dizini gibi) bir XML dosyasından alınabilir.

Başka bir örnek al. Microsoft Test Yöneticisi GUI (Visual Studio ile birlikte gelir), kullanıcıların GUI arayüzünden test çalıştırmaları başlatmasına izin verir, ancak aynı şeyi yapmak için bir komut satırı arayüzü de sağlar (komut satırı anahtarları ve girişlerinin bir kombinasyonunu kullanarak). Bu, testlerin başlatılmasını otomatikleştirmek için bir PowerShell veya DOS komut dosyasını bir araya getirebileceğimi ve ardından komut dosyalarının belki de her gece çalıştırılmasını sağlamak için zamanlanmış bir görev oluşturabilirim.

Bazı uygulamalarda, bir uygulamanın belirli seçeneklerle açılmasını belirten komut satırı anahtarları bulunur (örneğin, uygulamayı büyütülmüş bir pencerede açmak için '/ maximize' komutunu kullanabilirim).

Bir komut satırı arayüzünün kullanıma girebileceği birçok senaryo vardır. Bunlar sadece bazı örneklerdir.


1

Cümle tekrar dikkat edin: "Normal kullanıcı arayüzü sınıflarını bir komut satırı ile kolayca değiştirebilmek iyi bir fikirdir". Bu bir CLI yazmanız gerektiği anlamına gelmez, sadece kolayca yapabilirsiniz.

Yani, söylediği şey, kullanıcı arabiriminizin kodun geri kalanından ayrılması gerektiğidir.


2
Bence bir yorum yapmayı düşünüyorsun, değil mi?
Julio Rodrigues,

1

Bağımlıdır ve bağlı olduğumu söylediğimde, bu sadece birkaç ileri vakaya sahip olmaktan ibaret değildir, aynı zamanda uygulamaya ve hedef kitleye de bağlıdır. Oyunları denklemden kaldırdığımızı varsayarsak, o zaman benzer bir komutun muhtemel olmadığı ya da asla uygulanamayacağı yerlerde yazmış olabileceğiniz çok çeşitli uygulamalar vardır. Başımın üstünde, mobil (örneğin iOS, Android, vb.) Bir ortamı hedefleyen herhangi bir uygulamanın bu başlık altında kalması muhtemeldir.

Bunu göz önünde bulundurarak, genel yazılım alanında, görselleştirmeye büyük ölçüde bağımlı olan herhangi bir uygulamanın (örneğin, PowerPoint, Maya vb.) Bir komut satırı değişiminin uygulandığını görmesi pek mümkün değildir. Aslında, Maya gibi bir grafik yazılımı söz konusu olduğunda, tam ve uygun bir komut satırı sürümünün nasıl çalışacağını belirlemek iyi bir zihinsel egzersiz olabilir ve bunu kullanıcı açısından yapmak mümkün olmayabilir. Dolayısıyla, komut dosyası benzeri bir uygulamanın istenmesi mümkün olmasa bile istenebilecek veya istendiğinde istenen bir komutun olduğu durumlarda karşılaşılabilecek kesin yaygın uygulamaların olduğu açıktır.

Daha sonra, genel yazılım mimarisinin bakış açısını öneren biçime bakarsak, periyodik olarak kendinize “Kullanıcı arayüzü olmadan bu özelliğe nasıl erişebilirim?” Sorusunu sormanın mantıklı olacağını anlayabilirim. Genel olarak, bunu yapmanın bir yolu yoksa ve kullanıcı ile doğrudan etkileşime girmiyorsa (örneğin, jest girişi), genel mimarinin iyileştirilmesi gereken bir durum olabilir. Test kolaylığı sağlamak için, kullanıcı arayüzünden geçmeden doğrudan bir komut satırından çağırılmasalar bile, doğrudan komuta erişebilmek isteyeceksinizdir. Bu genellikle sağlam bir API'nin yerinde olması gerektiği ve teorik olarak iyi bir API'nin komut satırı veya kullanıcı arayüzü üzerinden erişime izin vermesi gerektiği anlamına gelir. Ayrıca, uzun vadede,

Günün sonunda, önerinin ne elde etmeye çalıştığının bir anlam ifade ettiğini düşünüyorum (örn. İyi bir API var ve kullanıcı arayüzünüzü bu noktadan kurgulayın), ancak kelime seçimi daha iyi olabilirdi. .


1
Genel olarak aynı fikirde değilim, ancak Maya'nın en güçlü yanlarından biri aslında çok güçlü bir komut dosyası çalıştırma API'sına (aslında MELScript, şimdi Python) sahip olmasıdır.
jwd

jwd - Maya seçtiğim bir örnek çünkü birkaç yıl önce kullandım, eğer aynı düşüncede daha iyi bir tane varsa bana bildirin. Belki de o kadar iyi olmasa da Bryce?
rjzii

0

Değişir.

Genellikle programlarımızı model / görünüm / kontrolörler veya model / görünüm / görünüm / model olarak bölümlere ayırırız. Modelin komut satırı erişimine izin vermesi gerektiği görünüyor, ancak denetleyiciden emin değilim. Doğal olarak, görünüm ne değiştiriliyor.

Alet zincirine bağlı olarak bir miktar fark olabilir. Code Complete bir Microsoft Press kitabıdır, bu nedenle belki de bu GUI için Microsoft teknolojilerini kullanıyorsunuz? Öyleyse, COM veya DCOM aracılığıyla arayüzleri göstermek için uygulamayı oluştururken bir onay kutusu olabileceğini düşünüyorum. Bazı Microsoft teknolojileri için, kaynak tablolarının ve iletinin aktarılmasının Sihirbazların hızlı bir şekilde prototip yapmanıza yardımcı olduğu her şeyle oldukça yoğun bir şekilde bağlantılı olduğunu düşünüyorum. Daha iyi olduğunu düşünüyorum, ancak MFC veya Formları sürdürüyorsanız, biraz acıtabilir.

Bazı durumlarda, GUI tabanlı programınız bir yönetim arayüzünün etrafındaki bir sarmalayıcı olabilir veya komut satırı arayüzü tarafından kontrol edilemeyecek kadar az bir mantığı olabilir. Ayrı bir konsol uygulaması oluşturmak daha hızlı olabilir ve yine de önemli olanı kodlamanıza, test etmenize veya kullanmanıza izin verir.

Tahmin ettiğim en önemli nokta, önerinin bir kural olmadığı. Bunu izlerseniz, siz veya bir müşterinin kliklemek yerine yazmayı tercih edebileceği durumlarda kolay ünite ve kabul testi veya geri dönüş arayüzü elde etmelisiniz. Kendisi için öderse, yapın. İyi şanslar.


4
-1: Kod Tamamlama programlama zanaat hakkında bir dil-agnostik kitaptır.
deworde

1
Asla başka türlü söylemedi.
Oyla tıklayın

Ve onun sorusu UI gelişimine özeldi ... Amacınız Bay Deworde?
Ian,

0

Komut satırı programının ne kadar yararlı olacağına bağlıdır. Haritaya rota çizmek veya 3 boyutlu oyun oynamak gibi bazı şeyler kendilerini komut satırı arayüzüne ödünç vermezler. Ancak sistem araçları gibi diğer şeyler komut satırından GUI'den çok daha iyidir, çünkü basit bir şekilde komut dosyası yazılabilir.

Richard Hipp bir keresinde ideal GUI işletim sisteminin, komut pencerelerini açmak için bir simge ve bir web tarayıcı açmak için başka bir simge ile boş bir masaüstü olduğunu söyledi. Neredeyse aynı şekilde hissediyorum. Bir komut satırı programı olarak faydalı olacak ve bu şekilde inşa etmek çok zor olmasa, bunu yapardım. GUI tamamen başka bir program olabilir, belki başka biri tarafından yapılmış olabilir!


Niçin bir haritada bir rota çizme kendisini CLI otomasyonuna borç vermiyor? Gibi bir PlotRoute(startPoint, endPoint)şey oldukça basittir.
Mason Wheeler

@MasonWheeler - Daha çok olacağına inanıyorumPlotRoute(startPoint, endPoint, chart)
Fabricio Araujo

0

Bugünlerde (en azından Java için) er ya da geç, tüm programlar er ya da geç bir web servisi (SOAP ya da Ajax ya da her ikisi) ekliyor gibi görünüyor. Yani genel olarak evet, düşünün, ancak daha iyi bir zihinsel benzetme ... ve daha muhtemel bir tane istiyorsanız, bir web servisi ön ucu komut satırından daha muhtemeldir.


0

Her şeye bakmanın farklı bir yolu var. Gitmenin tek yolu bir komut satırı olduğunu varsaymak yerine, neden konuşma kontrolünün kullanılabileceğini varsaymıyorsunuz? Tamamen farklı bir paradigma o zaman gereklidir.

Jobs Apple'ı ele geçirmeden önce, çok sofistike ses kontrol mekanizmaları araştırılıyordu. Apple bunu Siri gibi şeylerin lehine susturdu.

İç çekmek.

Popüler ve açık her zaman "en iyi" değildir.


Komut satırının ana nedenlerinden biri, temel olarak yazılımın işlevselliğini test edebilmek ve kodlayabilmektir. Sadece sesleri test etmek veya toplu bir komut dosyası çalıştırmak için seslerimizin ses kliplerini kaydetmek biraz zor olabilir (veya en azından disk hoggy).

0

Bu genellikle iyi bir fikirdir, evet.

Metaforla, insanlar bunu bir RESTful tasarım biçimi olarak düşünebilirler. .... tipik olarak (G) kullanıcı arayüzü, hesap oluşturma gibi karmaşık çok aşamalı işlemleri içerebilir.

Better that one stays away from multi-stage complexity through shopping-cart-like models for transactional setup.

Bir keresinde tarayıcıda bir drag'n'drop UI metaforu programladım. UX'in doğal hissetmesini sağlamak için arka tarafta çok karmaşık etkileşim kuralları . Bunu siteyi bir API yaparak çözdüm ve GUI eylem üzerine olay oluşturan tam bir uygulama oldu. Bir modül bu olayları yakaladı ve bir zamanlayıcıda bunları 'API çağrıları' olarak birleştirdi (ağ verimliliği için).

Sonuç tamamen RESTful bir çekirdek sistemdi. İkinci sonuç, üçüncü taraflar için bir arayüze sahip olduğumdan, işletme modeline göre üyelik profillerini kullanarak gösterebileceğim bir arayüzdü.


-1

Bir avantaj, UI'nin akışını kullanıcı bakış açısından düşünmeye zorlanmanızdır. (Neyi başarmaya çalışıyorum? Hangi bağlamı oluşturmam gerekiyor? Bu bağlamda, hedefe nasıl ulaşabilirim?)

"Banka hesabı oluştur" ile "ms word belgesi yaz" arasında büyük fark var. Bir CLI oluşturmasanız bile, sadece gerekli "CLI bağlamını" göz önüne almak için değer katabilir. Modeller sadece iş nesnesi modelinde yaşamaz!

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.