Yazılım tasarımını neden daha etkin yakalayamıyoruz? [kapalı]


14

Mühendisler olarak hepimiz eserleri (binalar, programlar, devreler, moleküller ...) tasarlıyoruz. Bu, bir tür sonuç (isim-tasarım) üreten bir faaliyettir (fiil-tasarım).

Sanırım hepimiz, tasarımın yapının kendisinden farklı bir varlık olduğu konusunda hemfikiriz.

Yazılım işindeki (aslında, ortaya çıkan ürün artefaktının geliştirilmesi gereken herhangi bir işte) önemli bir faaliyet, "tasarım (isim)" yi anlamaktır. Yine de, bir topluluk olarak, insanların kod tabanları hakkındaki gerçekleri yeniden keşfetmeye harcadıkları çabanın kanıtladığı gibi, onu kaydetmede neredeyse tamamen başarısız gibi görünüyoruz. Birinden size kodlarının tasarımını göstermesini ve ne elde ettiğinizi görmesini isteyin.

Yazılım için bir tasarıma sahip olduğumu düşünüyorum:

  • Yazılımın ne yapması gerektiği ve ne kadar iyi yaptığı konusunda açık bir spesifikasyon
  • Kodun açık bir sürümü (bu bölüm kolaydır, herkes sahiptir)
  • Kodun her bir parçasının spesifikasyonu elde etmeye nasıl hizmet ettiğine dair bir açıklama (örneğin, spesifikasyon parçaları ile kod parçaları arasındaki ilişki)
  • Bir mantığı kodu bu şekilde olduğunu neden olarak (örneğin, neden belirli bir seçim yerine başka)

Bir tasarım DEĞİL ne kod üzerinde belirli bir bakış açısıdır. Örneğin, [özel olarak seçmeyin] UML diyagramları tasarım değildir. Aksine, koddan türetebileceğiniz özellikler veya tartışmasız olarak koddan türetmek istediğiniz özelliklerdir. Ancak genel bir kural olarak, kodu UML'den türeyemezsiniz.

Neden 50 yıldan fazla yazılım geliştirdikten sonra, bunu ifade etmek için neden düzenli yöntemlerimiz yok? (Açık örneklerle benimle çelişmekten çekinmeyin!)

Yapsak bile, topluluğun çoğu “kod” almaya odaklanmış görünüyor ve isim-tasarım yine de kayboluyor. (IMHO, tasarım mühendisliğin amacı haline gelene kadar, tasarımdan çıkarılan eserle bunun üstesinden gelmeyeceğiz).

Tasarımları kaydetmenin bir yolu olarak gördünüz (onu tanımladığım anlamda)? Makalelere açıkça atıflar iyi olur. Sizce neden özel ve genel araçlar başarılı olamadı? Bunu nasıl değiştirebiliriz?

[ Yukarıdaki madde işaretli bakış açısını ortadan kaldıran kendi fikirlerim var, ama diğer insanların cevaplarıyla ilgileniyorum ... ve planımı uygulamak zor [[ve belki de gerçek sorun: -]]]]

DÜZENLEME 2011/1/3: Yanıt dizilerinden biri, "dokümantasyon" un (muhtemelen metinsel, özellikle resmi olmayan) yeterli olabileceğini ima ediyor. Sanırım buna inanmadığımı açıklığa kavuşturmalıyım. CASE araçları sahnede 80'lerden itibaren ortaya çıktı, ancak ilk araçlar çoğunlukla çizdiğiniz şeylerin şemaları için pikselleri yakaladı; araçlar tartışmasız ticari olarak başarılı olsa da, gerçekten çok yardımcı olmadılar. Önemli bir içgörü, ek "tasarım" eserleri resmi olarak yorumlanamazsa, ciddi bir araç yardımı alamayacağınızdı. Aynı görüşün uzun vadeli yararlı tasarım yakalama biçimleri için de geçerli olduğuna inanıyorum: eğer resmi bir yapıya sahip değilse, herhangi bir gerçek kullanım olmayacaktır. Metin belgeleri bu testte başarısız oluyor.


1
UML üzerinde anlaştı - en iyi iletişim aracı, tasarım açıklamasına katkıda bulundu, ancak kendi başına tasarım değil. En kötüsü, UML grafiksel kaynak kodudur.
Steve314

"ne kadar iyi işlediğini" ölçmek
Steven A. Lowe

Sistemler oluşturduğumda, birçok "işlevsel olmayan" gereksinimi karşıladım: bu dilde kodlanmış, bu veritabanını kullanıyor , 100mS ortalama yanıt süresi ile 1E10 kayıtlarını işliyor, ... Bunları şartnamenin dışında bırakamazsınız. (İşlevsel olmayan gereksinimler olmadan, sonsuza kadar döngü, herhangi bir işlevsel özellik için yeterli bir programdır). "Tasarım" yakalama ile ilgili tüm mesele, işlevsel olmayan başka bir gereksinimi ele almaktır: "sürdürülebilir".
Ira Baxter

Tartışmanız ilginç görünüyor ancak sorunun tam olarak ne hakkında olduğundan emin değilim. Tam olarak ilgilendiğiniz şeyi açıklığa kavuşturmak için somut bir örnek gibi bir şey vermeye çalışabileceğinizi mi düşünüyorsunuz? Sorunuzdaki 4 mermi noktasının tamamını gördüğünüz gibi tam olarak verebileceğiniz FFT örneği gibi bir şey ve belki de bir kez yakalanan sonuçlarla ne tür şeyler yapmak istediğinizi düşünüyorum.
n1ckp

Bu sorunun nedenleri hakkında hiçbir fikrim yok, ama bu Fred Brooks'un 'Tasarım Tasarımı' konusudur . (Zaten tanıdıklarınız varsa özür dileriz.) Programlama ve mimariden örnekler tartışıyor. Özellikle rasyonelleri yakalamanın (hem tasarım hem de reddedilen alternatif tasarımlar için) gerçekten yararlı olduğunu ve mevcut araçlar tarafından iyi sunulmadığını belirtiyor.
Paul D.Waite

Yanıtlar:


8

Bence bu konuda hala iyi olmamamız için birkaç neden var.

  1. İnsanlar uzun zamandır yazılım ev gibiydi ve yapımdan süreçler ve fikirler kullanıyorlardı. "Yazılım mimarı" tüm programcıların istediği bir başlıktı. Son on yıl boyunca yazılım mimarı neredeyse ölmüştü. Yazılımın nasıl çalışması ve bakması gerektiğini söyleyen bir mimara sahip olduğunuz ve daha sonra insanların nasıl inşa edilmesi gerektiğine dair diyagramlar oluşturmasını ve son olarak bu güzel iş akışlarını / UML diyagramlarını belirtmek için kod maymununa sahip olmasını sağlayan şelale süreçleri fikri, bu fikir şimdi yaygın olarak alay. Aslında, tüm endüstri 40 yıldır yanlış yola giriyordu.

  2. Kullandığımız araçlar sürekli olarak değişiyor ve gelişiyor. Programlama mantıklı bir bulmaca ve bu bulmacayı soyutlamak ve anlaşılır kılmak için daha iyi fikirler ve teknikler geliştiriyoruz. Bunu modelleme şeklimiz aynı hızda gelişmelidir, ama geride kalıyor. Programlama bulmacasını soyutlamak için geliştirilmiş teknikler aynı zamanda karmaşıklığı artırabileceğimiz anlamına gelir. Ve biz de öyle. Programlama her zaman, programcıların üstesinden gelebileceğimiz karmaşıklığın kenarlarında yatar.

  3. Programı tanımlamanın yollarını çizmek bir tür soyutlamadır. Yazılımı soyutlamanın iyi bir yolunu bulabilirsek, bu soyutlamayı doğrudan geliştirme araçlarına da koyabilir ve bu nedenle programlamaya başka bir soyutlama / basitleştirme ekleyebiliriz. Bu birçok kez oldu. Bu tür soyutlamalara örnekler fonksiyonlar, sınıflar ve kütüphanelerdir.

  4. Bu nedenle; Yazılımın başarılı ve doğru bir modeline sahipseniz , bu model yazılıma eşdeğer olacaktır . Bu da tüm çabayı anlamsız kılıyor, bu da yukarıdaki 1. maddeyi destekliyor: Yazılımın modellenmesi, daha önce düşünülenden çok daha az kullanışlı. Bunun yerine koddan yazılımla ilgili verileri çıkarmak daha iyidir. Kodun gerçekte nasıl göründüğünden bir UML modeli oluşturmak, bir UML modeli oluşturmaktan ve bu teorik modeli uygulamaya çalışmaktan çok daha aydınlatıcıdır.


2
Son noktanıza katılmayın. Evet, yazılıma oldukça eşdeğer olacak, ancak bir modeli yeniden çizmek, bir şeylerin ne kadar iyi bir fikir olmadığını öğrendiğinizde, gerçek yazılımı yeniden düzenlemekten daha kolaydır. Tasarım adımının önemini küçümsemem.
Joris Meys

1
@Joris Meys: Sorun, uygulayana kadar neyin iyi neyin iyi olmadığını bilmemeniz. (Önemsiz durumlar hariç, ancak yine de bir UML diyagramını çok fazla kullanmayacaksınız). Ayrıca kodu yeniden düzenlemenin ne kadar zor olduğunu fazla tahmin etmemelisiniz. XP ve Test Odaklı Tasarım üzerine Kent Becks kitaplarını okumanızı tavsiye ederim.
Lennart Regebro

@Lennart: Tahmin için
teşekkürler

2
@Lennart: İş ile aranız arasındaki fark, şu anda programlanabilir soyutlama setinizin bunu nasıl yaptığını bilmememe rağmen, bir şekilde ifade edilen bir spesifikasyonun gerekli olabileceğini kabul ediyor olmanızdır. Ama ana frekansları çıkaran bir sinyal işleme programına ihtiyacım olduğunu düşünün. Dikkat nasıl önermedim. Bir Fast Fourier Dönüşümü kullanmaya karar verebilirsiniz ve kesinlikle FFT bitlerini uygulayan kodun her yerinde ayak izleri bulacağım. Ancak açıkça kaydedilmiş bir FFT kullanmaya karar verdiğiniz gerçeği nerede? Okurlarınız her şeyi bilmedikçe buna ihtiyacınız olduğuna inanıyorum.
Ira Baxter

1
@Ira Baxter: Peki ya "FFT ile sinyal işlemeyi seçtik?" Kaynak kodunda yorumlar var. Ayrıca bir README dosyasına da yazabilirim. Spesifikasyonun açık ifadesi koddur. "FFT ile uygulamayı seçtik" gibi metin satırları açık değildir, orijinal yazınız anlamında da tasarım değildir. Uygulamanın belgeleri. Sonunda tartışmalı bir moddasınız gibi görünüyor, ama neye karşı çıkmaya çalıştığınızı anlamıyorum.
Lennart Regebro

5

Yazılım izlenebilirlik literatürünü gözden geçirmek isteyebilirsiniz. Belirli bir sırada değil:

  • CUBRANIC, D., MURPHY, GC, SINGER, J. ve BOOTH KELLOGG, S. Hipikat: yazılım geliştirme için bir proje belleği. Yazılım Mühendisliği İşlemleri 31, 6 (2005), 446-65.
  • TANG, A., BABAR, MA, GORTON, I. ve HAN, J. Mimari tasarım mantığının kullanımı ve dokümantasyonu üzerine bir araştırma. 5. Yazılım Mimarisi IEEE / IFIP Konferansı Proc (2005).
  • RAMESH, B., POWERS, T., STUBBS, C. ve EDWARDS, M. Uygulama gereksinimlerinin izlenebilirliği: Bir vaka çalışması. Gereksinimler Mühendisliği Uluslararası Belirtisi Proc (York, 1995).
  • HORNER, J. VE ATWOOD, ME Tasarım gerekçesi: gerekçe ve engeller. İnsan-Bilgisayar Etkileşimi 4. İskandinav Konferansı Proc: Değişen Roller (Oslo, Norveç, 2006).
  • CLELAND-HUANG, J., SETTIMI, R., ROMANOVA, E., BERENBACH, B. ve CLARK, S. Otomatik izlenebilirlik için en iyi uygulamalar. Computer 40, 6 (Haziran 2007), 27-35.
  • ASUNCION, H., FRANÇOIS, F., ve TAYLOR, RN Uçtan uca endüstriyel yazılım izlenebilirlik aracı. Avrupa Yazılım Müh Conf ve ACM SIGSOFT 6. Yazılım Mühendisliği Temelleri (ESEC / FSE) Uluslararası Ortak Toplantısı Proc (Dubrovnik, 2007).

Bunun buzdağının sadece görünen kısmı olduğuna dikkat edin ve eminim bazı önemli kağıtları dışarıda bıraktım.

Ayrı bir notta, Arcum üzerinde kendi çalışmam, programcıların IDE'ye çapraz tasarım deyimlerini kullandığını ifade etmeleri için bir araçtı. Bir kez ifade edildiğinde, programcılar kaynak kodlarını alternatif uygulamalar kullanmak üzere dönüştürebilirler:

Bu arada, Arcum aynı zamanda DMS çalışmanızla da ilgilidir.


1
Bunun için +1. RT her şey değildir, ama aynı eski mazeretleri yapmak yerine problemi çözmek için birkaç olumlu adımdan biridir .
Aaronaught

2

UML, benim düşünceme göre bir binaya yönelik planların ne olduğunu bir programdır. Planlar tek başına bir tasarım değildir, bunun için malzeme özelliklerine (kullanılan kod araçlarına), binanın genel bir görünümüne (GUI tasarımları da dahil olmak üzere tüm yazılımın bazı şematik gösterimi), binanın çevreye nasıl ekildiğine ihtiyacınız vardır. (yazılımın diğerleriyle nasıl etkileşime girdiğinin / işletim sisteminin içine nasıl yerleştirildiğinin açık bir şeması), iklim ve toprağın nasıl durduğunu (donanımla etkileşim), ... Tasarımla ilgili çok sayıda kitap onu tanımlamaya çalışır, ancak olduğu gibi bilimdeki birçok şey, her bilim insanının kendi tanımı vardır.

Şimdi, kodu UML'den türeyemeyeceğinizi de gözlemlemenize katılmıyorum. Belirtilen ek bilgilere sahipseniz bunu yapabilirsiniz. Ama gerçek kod artık tasarım değil, bu eser. Gerçek taşları ve betonu da bir plandan çıkaramazsınız, ancak gerçek taşları ve betonu doğru biçimde ve doğru yere koyma planına ihtiyacınız vardır.

Bu ışık altında, aşağıdaki makaleyi ilginç buldum (grafik yazılımı ararken farklı bir bağlamda tanıştım, ancak yine de ...). Bir tasarımı tanımlamak için grafik yaklaşımı benim için mantıklıydı, yine de - bu, bence tasarımın sadece bir parçası. İlginç olan, bu yaklaşımın aşağıdaki makalelerde belirtildiği gibi tasarımları (yazılımı yeniden düzenlemenin aksine) anlamak ve yeniden düzenlemek için bir çerçeve sağlamasıdır:

Tasarımı tanımlamak ( yapılandırılmış tasarım (HIPO Grafikleri) veya entegre program tasarımı , tasarım kalıpları , vb. ) Gibi birçok başka yaklaşım vardır .

Yine de, endüstri standardı bir set olmadığı sürece, bunu ifade etmenin "düzenli" bir yolunu bulması pek olası değildir. 50 yaşından sonra bile. Ve dürüst olun, şirketiniz bir tasarımı ifade etmenin iyi bir yolunu bulursa, onu dünyayla paylaşır mısınız?


Şirketiniz bunu yapmanın iyi bir yolunu bulursa, programcılar diğer herkese çok çabuk darn söylerdi. :-)
Lennart Regebro

Sanırım UML (ve diğer "tek" gösterimler) hakkındaki fikrimi kaçırdınız. Koddan önce UML, yazılımı nasıl oluşturmak istediğinize dair bir kısıtlamadır. Diğer tüm notasyonlar da (evet, bunların çoğunu gördüm, bir süredir bulundum). Bir kısıtlama göz önüne alındığında, bu kısıtlamayı kod toplantısı üretmek mümkündür (şaka yöntemi: tüm olası programları üretmek ve hangilerinin kısıtlamaya uyduğunu görmek için, bunlardan birini seçin). Bu anlamda "UML'den kod oluşturabilirsiniz". Ancak (sınıf diyagramlarına sadık kalırsak) bu kod istediğiniz işlevi yerine
getirmez

... ve diğer gösterim şemalarının çoğu da bundan muzdariptir, programın ne yapması gerektiğine dair bir spesifikasyon yakalamazlar. Ayrıca gerekçe gibi bir şey sağlamıyorlar; UML grafiğiniz neden şekli? Grafiği bozmadan kodun hangi kısmını değiştirebilirim? Grafiğin arkasındaki niyete zarar vermeyecek şekilde değişebilir miyim?
Ira Baxter

@Ira: Web sayfanızı ziyaret ettikten sonra benim için daha açık hale geldi. Ancak itiraf etmeliyim ki, bu konularda üst düzey bir anlambilimsel tartışma benim uzmanlığımın ötesindedir. Yine de, gerçek kodu tasarımın bir parçası olarak görürseniz , gerçek eser nerede? UML -veya başka bir gösterim- alçakgönüllülüğe göre kod yapısının bir taslağı ve tasarımın bir parçası olarak adlandırmak istediğim bir şey . Aslında gerçek koddan daha fazlası. zihin parçası . Bu tasarım değil, yine de buna önemli bir katkı. yine, benim düşünceme göre. Gerekçe vb. Açıklandığı gibi buna eklenebilir.
Joris Meys

@Joris: Çoğu diyagramatik notasyon, koddan (en azından bittikten sonra) projeksiyonlar (çıkarılan eserler) olarak veya kodun oluşturulması için bir rehber olarak düşünülebilir (plan). Çok sayıda olası diyagram var (bazıları cevabınızda listelenmiştir). Hangileri sahip olduğunuz kod için temeldir ve hangileri sadece kazadır? Akış şemaları digramlardır, bu yüzden kalifiye olmalıdırlar; Henüz bazı kod öbek akış şemaları edeceğini oldukça eminim değil onun tasarımının bir parçası olarak kabul edilebilir. Peki, temel olan nedir? Kazara ne var?
Ira Baxter

2

Kendi kişisel deneyimimden, yazılım tasarımını iyi yakaladığımızı iddia ediyorum. Platformumuzda şimdiye kadar uyguladığımız her özellik için bir gereksinim ve tasarım dokümanları veritabanına sahibiz. Durumumun belki de benzersiz olduğunu düşünüyorum. İşte düşünmeniz gereken bazı şeyler.

Ekibimdeki herkesin mühendislik derecesi var ... çoğunlukla EE veya CE. Mühendislik size müfredatın bir parçası olarak tasarım öğretir.

Ben CS kökenli gelen bir çok sözde yazılım mühendisleri olduğunu düşünüyorum. Yazılım tasarımı, çoğu CS programının ayrılmaz bir parçası değildir. Tüm CS binbaşılarının tasarımda kötü olduğunu söylemiyorum, ancak çoğunun kendisine öğreten resmi bir eğitiminin olmadığından bahse girerim. Bence bir çok insan, eğer programlayabiliyorsanız, yazılım tasarlayabileceğinizi varsayar ki bu doğru değildir. Birçok programcının mühendislik altyapısı olmadığı göz önüne alındığında, birçok yazılım projesinin tasarımı yakalamada iyi bir ekibe sahip olmaması gerçekten şaşırtıcı değildir.


Öyleyse hangi özel yazma gereksinimlerini ve tasarım belgelerini kullanıyorsunuz? (Biyografine baktım ve birini savunma alanından görmeyi bekliyordum ve şaşırdım). Gereksinim gereği bazı doğal dil metni mi demek istiyorsunuz? ... eğer öyleyse, onlar hakkında tartışmanız yok mu? (Doğal dil gereksinimlerini biçimsel özelliklerden ayırırım). Tamamlandı mı? Peki ya tasarım belgeleri? Mevcut nakliye sistemi için tamamen güncel mi? Pek çok sözde programcı ve yazılım mühendisinin olmadığını kabul edeceğim, bu yüzden ne yapmaları gerektiğini tartışmaya devam edebiliriz.
Ira Baxter

1
Yöntemimize özel bir ad olduğundan emin değilim. Gereksinimlerimiz, doğal dil gereksinimleri ile üst düzey tasarım belgeleri arasında karma olarak adlandırdığım şeydir. Genellikle iki düzenleme turumuz vardır. İlk olarak, bir özelliğin ne yapması gerektiğini basit İngilizce olarak belgeliyoruz. Ardından, tam olarak nasıl çalışacağını kullanıcının bakış açısından belirleriz. Belgenin iki hedefi var. Birincisi, iş ihtiyaçlarımızı karşıladığımızdan emin olmak için Pazarlama ekibimiz tarafından incelenebilecek bir belge sunmak istiyoruz. İkincisi, KG ekibimiz tarafından test etmek için kullanılabilecek bir belge sunmak istiyoruz.
Pemdas

1
Tasarım belgelerimiz çok daha resmi ve ayrıntılı. Her zaman aşağıdakileri içerir: Bir tür kullanım durumu analizi, esnafların herhangi bir açıklaması veya bir şeyler yapmanın belirli bir yolunu seçmemizin nedenleri, diğer tasarımlara referanslar, açık arayüz tanımları, veri yapıları ... vb. Belirli bir kodun belirli gereksinimleri nasıl karşıladığına ilişkin açık yorumlarımız olması gerekmez. Bunun önemli olup olmadığına dair kararsızım.
Pemdas

1
Belgelerimizin% 95 oranında güncel olduğunu söyleyebilirim. Buradaki birkaç şey çatlaklardan geçiyor.
Pemdas

2

İki sorun görüyorum.

Birincisi, kod ve dokümantasyonu senkronize tutmak kanlı zor. Ayrı olmaları halinde ayrılırlar ve dokümantasyon işe yaramaz hale gelir. Programcılar, onları senkronize tutma işini yapmak için araçlar kullanmaya çalıştılar (CASE araçları gibi), ancak bu araçlar programcılar ve kodları arasında yer aldı ve bu da yarardan çok zarar verdi. Etki alanı güdümlü tasarımın temel görüşlerinden biri (Evans, 2004) iyi tasarımın gerçekten zor olmasıdır, bu yüzden bir şeyden kurtulmak için şunları yapmalısınız:

  • iyi tasarımın büyük faydalar sağlayacağı, çekirdek etki alanı adı verilen programınızın mümkün olan en küçük alanını seçin
  • tüm ekip üyelerinin her zaman kullandığı yaygın bir dil biçiminde iyi bir tasarım elde etmek için gerçekten çok çalışmak
  • Mümkün olduğunca tasarımı kodun bir parçası haline getirin

Tasarım yapma şeklimizdeki diğer büyük sorun, tasarım yöntemlerimizin yeterince matematiksel olmamasıdır. Sızdıran soyutlamalar, onlardan sağlam sonuçlar çıkarmak için kendilerini ödünç vermez ve katı bir şekilde uygulanan mantık ve açık gerçek dünyasına, programcıların çoğunlukla utangaç olduğu matematik denir.

Resmi yöntemler gibi sahip olduğumuz birkaç matematiksel araç çok hantal.

Harita azaltma programlamada matematiğin güzel bir örneğidir. Ana fikir şudur: İlişkisel, ikili bir işleminiz varsa, yürütülmesini çok kolay bir şekilde dağıtabilirsiniz. İkili işlem iki parametreli bir işlevdir, ilişkilendirilebilirlik (a + b) + c = a + (b + c)

a1 + a2 + ... + a99 + b1 + b2 + ... + b99 + c1 + c2 + ... + c99 olduğunu

(a1 + a2 + ... + a99) + (b1 + b2 + ... + b99) + (c1 + c2 + ... + c99), burada As, Bs ve Cs farklı yerlere önemsiz bir şekilde eklenebilir, sonuçları toplanır ve kısa sürede özetledi.

Harita azaltma gülünç derecede basit bir fikirdir. Tek bir kağıtta tarif edilebilir. Eğer oldukça küçük bir kağıda sığarsa, okuyucunun birliktelik kavramını sağlam bir şekilde kavradığını varsayabilirsiniz. Şimdi, ilişkisellik terimini kullanmadan veya dolaylı olarak bahsetmeden birine harita küçültmeyi açıklamaya çalışın. Sana meydan okuyorum.

Matematiksel soyutlamalar olmadan yazılım tasarımı, geometri öğrenmek için uğraşmadan mimarlık yapmaya çalışmak gibidir.

Belki Haskell bunu zamanla düzeltebilir. Kategori teorisindeki kavramların programları tanımlamak için kullanılması bana umut vericidir. Kategori teorisi o kadar soyuttur ki matematikçilerin bile bunun için çok az kullanımı vardır, ancak görünüşe göre tanınmayacak kadar soyut kategoriler, yazılımın yapısını tanımlayacak kadar soyut görünmektedir. Öğreneceğiz. Yavaşça.

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.