Ancak draw () yöntemi kullanıcı arayüzünün ne olduğuna bağlı değil mi?
Pragmatik bir bakış açısına göre, sisteminizdeki bazı kodların Rectangle
kullanıcı sonu gereksinimi olan bir şey gibi nasıl çizileceğini bilmesi gerekir. Ve bu, bir noktada, pikselleri rasterleştirmek veya bir konsolda bir şey görüntülemek gibi gerçekten düşük seviyeli şeyler yapmaktan kaynaklanacak.
Birleşme açısından benim için soru , bu tür bilgilere kime / neye ve hangi dereceye kadar ayrıntıya (ne kadar soyut, örneğin) dayanmalıdır?
Soyut Çizim / Render Yetenekleri
Çünkü, üst seviye çizim kodu sadece çok soyut olan bir şeye bağlıysa, bu soyutlama, hedeflemeyi düşündüğünüz tüm platformlarda (somut uygulamaların kullanılmasıyla) çalışabilir. Tartışmalı bir örnek olarak, bazı çok soyut IDrawer
arabirimler hem konsol hem de GUI API'lerinde arsa şekilleri gibi şeyler yapabilme yeteneğine sahip olabilir (konsol uygulaması konsola ASCII sanatı ile 80xN "resim" gibi davranabilir). Tabii ki bu, tartışmalı bir örnek çünkü yapmak istediğiniz genellikle bu değil, bir görüntü / çerçeve tamponu gibi bir konsol çıktısını ele almak; genellikle çoğu kullanıcı sonu gereksinimi, konsollarda daha fazla metin tabanlı etkileşimi gerektirir.
Bir diğer husus, istikrarlı bir soyutlama tasarlamanın ne kadar kolay olduğu? Çünkü hedeflediğiniz her şey modern GUI API'leri ise, çizgi çizme, dikdörtgenler, yollar, metin, bu tür şeyleri (sınırlı bir ilkel kümesinin basit 2D rasterleştirilmesi) gibi temel şekil çizme yeteneklerini ortadan kaldırmak için kolay olabilir. , hepsi için çeşitli alt tipler üzerinden kolayca ve düşük maliyetle uygulanabilen tek bir arayüz ile. Eğer böyle bir soyutlamayı etkili bir şekilde tasarlayabilir ve tüm hedef platformlara uygulayabilirseniz, o zaman çok daha az bir kötülük, bir kötülük olsa bile, bir şekil veya GUI kontrolü için ya da böyle bir kullanarak kendini nasıl çizeceğini bilmek için söyleyeceğim. soyutlama.
Ancak, ihtiyaçlarınız her biri için en modern gerçek zamanlı 3D renderleme / gölgeleme tekniklerini kullanmak iken Playstation Portable, iPhone, XBox One ve güçlü oyun bilgisayarı arasında değişen kanlı ayrıntıları soyutlamaya çalışıyorsunuz. . Bu durumda, temel donanım yetenekleri ve API'ler bu kadar çılgınca değiştiğinde oluşturma ayrıntılarını soyutlamak için soyut bir arayüz bulmaya çalışırken, zamanın büyük olasılıkla tasarımı ve yeniden tasarlanması, kesin olarak tekrarlanan tasarım olasılıkları beklenmedik bir şekilde değişebilir. keşifler ve aynı şekilde, temel donanımın bütün benzersizliğinden ve gücünden faydalanamayan en düşük ortak payda çözümü.
Bağımlılıkların Kararlı, "Kolay" Tasarımlara Doğru Akışı
Kendi alanımda bu son senaryodayım. Radikal olarak farklı temel yetenekleri ve API'leri olan çok sayıda farklı donanımı hedefliyoruz ve hepsine hükmetmek için tek bir renderleme / çizim soyutlaması bulmaya çalışmak sınırsızdır umutsuz (sadece bir oyun gibi etkili bir şekilde yaparak dünyaca ünlü olabiliriz) sektöründe değiştirici). Yani benim durumumda en son istediğim şey analog gibi Shape
ya Model
da Particle Emitter
bu çizimi mümkün olduğu kadar en üst düzeyde ve en soyut şekilde ifade etse bile, kendini nasıl çizeceğini biliyor ...
... çünkü bu soyutlamalar doğru tasarlanamayacak kadar zor, ve bir tasarımın doğru olması zor ve her şey buna bağlı olduğu zaman, buna bağlı olarak her şeyi kopartan ve parçalayan en pahalı merkezi tasarım değişikliklerinin bir reçetesi. Bu nedenle, istediğiniz son şey, sistemlerinizdeki bağımlılıkların, soyut tasarımlara doğru gelemeyecek kadar zor (akıcı değişiklikler olmadan dengelenmek için çok zor) olmasıdır.
Zor Kolay Bağımlıdır, Kolay Değil Zor Bağımlıdır
Öyleyse yaptığımız şey, bağımlılıkların tasarımı kolay olan şeylere doğru akmasını sağlamak. Çokgenler ve materyaller gibi şeyleri depolamaya odaklanan soyut bir “Model” tasarlamak ve bu tasarımı doğru yapmaktan çok daha kolaydır; bir PC'den PSP kadar farklı olan donanım için düzenli olarak talep eder.
Bu yüzden bağımlılıkları, tasarımı zor olan şeylerden uzaklaştırıyoruz. Soyut modeller yapmak yerine, kendilerini tümüyle bağlı oldukları bir soyut işleyici tasarımına nasıl çekeceklerini bilmek (ve bu tasarım değişirse uygulamalarını bozmak) yerine, sahnemizdeki her soyut nesneyi nasıl çizeceğini bilen soyut bir işleyicimiz var ( modeller, partikül yayıcılar, vb.) ve böylece RendererGl
, bir başka PSP'ler için RendererPsp
, başka bir cep telefonu vb. gibi PC'ler için bir OpenGL oluşturucu alt tipi uygulayabiliriz . işleyiciden sahnedeki çeşitli varlık türlerine (modeller, parçacıklar, dokular vb.), tersi olmaz.
- Bob Amca'nın afferent / efferent coupling metriklerinden biraz farklı bir anlamda "stabilite / dengesizlik" kullanıyorum, ki bu anlayabildiğim kadarıyla değişimin zorluğunu ölçüyor. Stabilite metriği orada faydalı olmasına rağmen, “değişim gerektirme olasılığı” hakkında daha fazla konuşuyorum. "Değişim olasılığı", "değişim kolaylığı" ile orantılı olduğunda (örneğin: değişiklik gerektirmesi muhtemel olan şeyler, Bob Amca'nın metriğindeki en yüksek kararsızlığa ve afferent bağlantılara sahipse), bu tür olası değişikliklerin yapılması ucuz ve müdahaleci olmayan herhangi bir merkezi tasarıma dokunmadan yalnızca bir uygulamanın değiştirilmesini gerektirir.
Kendinizi merkez üssünüzde merkezi bir seviyeden soyutlamaya çalışıyorsanız ve inatla kafaları duvarlara çarpmak yerine sürekli tasarlamak zordur ve her ay / yılda sürekli olarak 8.000 kaynak dosyanın güncellenmesini gerektiren izinsiz değişiklikler yapmak ona bağlı olan her şeyi kırmak, benim bir numaralı önerim bağımlılıkları tersine çevirmeyi düşünmektir. Kodları, tasarımı zor olan şeyin tasarlanması zor olan şeylere bağlı olarak değil, tasarımı daha kolay olan her şeye bağlı olacak şekilde yazıp yazamayacağınıza bakın. Tasarımlardan (özellikle arayüz tasarımlarından) bahsettiğimi ve uygulamalardan bahsetmediğimi not edin: bazen tasarımları kolay ve uygulaması zor, ve bazen işleri tasarlamak zordur ancak uygulaması kolaydır. Bağımlılıklar tasarımlara doğru akar, bu nedenle odak noktası, bağımlılıkların akış yönünü belirlemek için burada bir şey tasarlamanın ne kadar zor olduğuna odaklanmalıdır.
Tek Sorumluluk İlkesi
Bana göre SRP burada genellikle çok ilginç değil (içeriğe bağlı olsa da). Demek istediğim, net ve korunabilir şeyler tasarlamada ipler dengeleyici bir hareket Shape
var ama nesnelerin nasıl çizileceğini bilmiyorlarsa nesnelerinizin daha ayrıntılı bilgi vermesi gerekebilir ve örneğin çok anlamlı şeyler olmayabilir. belirli bir kullanım bağlamında, onu yapılandırmaktan başka bir şekilde yapmak ve çizmek. Hemen hemen her konuda takaslar var ve bazı bağlamlarda deneyimlerime göre kendilerini böyle bir bakım kabusu haline getirebilecek şeyleri fark etmelerini sağlayacak SRP ile ilgili değil.
Bağlama ve bağımlılıkların sisteminizde aktığı yönle ilgili çok daha fazla şey var. Her şeyin bağlı olduğu soyut bir oluşturma arabirimini yeni bir hedef API / donanıma (çünkü kendilerini çizmek için kullandıkları için) taşımaya çalışıyorsanız ve orada etkin bir şekilde çalışmasını sağlamak için tasarımını önemli ölçüde değiştirmeniz gerektiğini fark ediyorsanız, o zaman Bu, sisteminizde, kendilerini nasıl çizeceklerini bilen her şeyin uygulamasının değiştirilmesini gerektiren çok pahalı bir değişikliktir. Ve bu, doğru şekilde önceden tasarlanması çok zor olan soyutlamalara doğru akan bir bağımlılık yüküne karşılık gelirse, kendilerini nasıl çizeceklerinin farkında olan şeylerle karşılaştığım en pratik bakım konusu.
Geliştirici Gururu
Bu noktadan bahsediyorum çünkü deneyimlerime göre, bu genellikle tasarımların bağımlılığı yönünü daha kolay olan şeylere doğru yönlendirmenin önündeki en büyük engeldir. Geliştiricilerin burada biraz hırslı olması ve “Platformlar arası soyutlama soyutlamalarını hepsine hükmedecek şekilde tasarlayacağım, diğer geliştiricilerin aylarca harcadığı şeyi çözeceğim ve alacağım çok kolay ” dedi. bu doğru ve desteklediğimiz her platformda sihir gibi çalışacak ve her biri için son teknoloji ürünü oluşturma tekniklerini kullanacak, zaten kafamda düşündüm. "Bu durumda, bunu yapmaktan kaçınmak ve sadece bağımlılıkların yönünü çevirmek ve uygulamada basitçe ucuz ve yerel yinelenen değişikliklere nihayetinde pahalı ve yinelenen merkezi tasarım değişikliklerini çevirmek için pratik çözüme direnirler. Böyle bir soyut seviyeye tasarım yapmak ve tüm stratejisini yeniden gözden geçirmek zor bir şey olduğunda, geliştiricilere bir tür "beyaz bayrak" içgüdüsünün olması gerekiyor, aksi halde çok fazla keder ve acı çekiyorlar. Böyle hırsları ve mücadele ruhunu, dünyayı fethediyor hırsları arayüz tasarımı seviyesine getirmekten çok, tasarımı daha kolay olan en modern uygulamalara aktarmayı öneriyorum.