OOP kolaylaşıyor mu yoksa zorlaşıyor mu? [kapalı]


36

Nesneye Yönelik Programlama kavramları, programcılara yıllar önce tanıtıldığında ilginç görünüyor ve programlama daha temizdi. OOP böyleydi

Stock stock = new Stock();
stock.addItem(item);
stock.removeItem(item);

Kendini açıklayıcı bir adla anlamak daha kolaydı.

Ancak, Veri Transferi Nesneleri, Değer Nesneleri, Havuz, Bağımlılık Enjeksiyonu vb. Yukarıdakileri elde etmek için birkaç sınıf (örneğin, özet, fabrika, DAO vb.) Oluşturmanız ve birkaç arayüz uygulamanız gerekebilir.

Not: İşbirliği, Test Etme ve Entegrasyonu kolaylaştıran en iyi uygulamalara karşı değilim.


23
İyi bir yazılım mimarisi oluşturmak her zaman zor olmuştur ve (büyük olasılıkla) her zaman olacaktır.
johannes,

6
Ben adlandırmak istiyorum addItemiçin addve removeItemiçin remove. Çünkü okumak daha kolay. stock.add(item)veya stock.remove(item). Ve daha fazla OOP odaklı.
razpeitia

1
Orijinal OOP, gösterdiklerinize neredeyse hiç benzemiyordu. OOP sözdizimi ile ilgili değil , Smalltalk tarafından popüler hale getirilmiş bir tür soyutlama ile ilgili. Bu illa ki noktanızın yanlış olduğunu ya da öncül kusurlu olduğunu kanıtlamaz; aksine, anladığından daha doğru.
Konrad Rudolph

1
mantığınızla elmaları ve portakalları karşılaştırıyorsanız, zorunlu programlama (yani döngüler ve if koşulu) bugün sahip olduklarımızdan daha basittir. Zorunlu programlama, sınıflar / OOP için yapı taşları ve sınıflar / OOP, tasarım desenleri için yapı taşlarıdır. İşler ilerledikçe işler daha karmaşık hale gelir, çünkü daha karmaşık problemleri çözersiniz.
Yalan Ryan

2
@LieRyan - Sorunları karmaşık hale getirdim, çünkü sorumlu hiç kimse bunları basit zorunluluklu programlama ile çözemedi ve OOP'un üstüne tek başına uygulanması gereken basit zorunluluk çözümünün üzerine tasarım desenleriyle saldırdı.
mouviciel

Yanıtlar:


35

OOP, kuruluşundan bu yana pek değişmedi. Birkaç yeni açı keşfedildi, ancak temel ilkeler hala aynı. Bir şey olursa, yıllar boyunca toplanan toplu bilgi, programcının hayatını zorlaştırmaktan daha kolay hale getirir. Tasarım desenleri bir engel değildir; Yıllar ve yıllar süren deneyimlerden arındırılmış standart sorunlara bir araç kutusu çözümleri sunarlar.

Peki neden bugün OOP'yi kullanmaya başladığınızdan daha karmaşık olarak algılıyorsunuz?

Bunun bir nedeni, maruz kaldığınız kodun daha karmaşık hale gelmesi olabilir - OOP daha karmaşık hale geldiği için değil, öğrenme basamaklarında ilerlemiş olduğunuz ve daha büyük ve daha karmaşık kod tabanları okuduğunuz için.

Diğer bir sebep, karmaşıklık paradigması değişmese de, ortalama bir yazılım projesinin boyutunun ve karmaşıklığının çok iyi olması olabilir. Yirmi yıldan daha kısa bir süre önce bir sunucuda bir geliştiricinin ıslak rüyası olacak müşteri sınıfı cep telefonlarında işlem gücü mevcutken , genel kamuoyu temelde kaygan animasyonlu GUI'leri en ucuz fırlatma uygulaması ve giriş seviyesi masaüstü bilgisayarın daha güçlü olması için bekliyor 1980'lerin bir "süper bilgisayarı" ndan, çubuğun Smalltalk ve C ++ 'ın ilk günlerinden beri kaldırılmış olması doğaldır.

Ve sonra, modern uygulamalarda, eşzamanlılık ve paralelliğin istisnadan ziyade norm olduğu ve uygulamaların sık sık farklı makineler arasında iletişim kurmaya, bir protokol protokolünün tamamını çıkarmaya ve ayrıştırmaya ihtiyaç duyduğu gerçeği var. OOP örgütsel bir paradigma olarak harika olsa da, diğer paradigmalarda olduğu gibi sınırlamaları vardır: örneğin, eşzamanlılık için çok fazla soyutlama sağlamamaktadır (çoğu uygulama tamamen ya da sonradan düşünülmüş, ya da tamamen kütüphanelere dış kaynaklı) ve ayrıştırıcı oluşturmak ve verileri dönüştürmek için mümkün olan en iyi yaklaşım değildir. Modern programlama sık sık OOP paradigmasının sınırlarını zorlamaktadır ve tasarım desenleri yalnızca sizi o kadar uzağa götürebilir. (Şahsen, Tasarım desenlerine ihtiyacımız olduğunu bunun bir işareti olarak görüyorum - paradigma bu çözümü kullanıma sunmuş olsaydı, bu sorunlar için daha anlamlı olurdu ve standart çözümler açık olurdu. Metod kalıtımını tanımlayacak bir tasarım deseni yoktur, çünkü OOP'nin temel bir özelliğidir; ancak bir Fabrika Deseni var, çünkü OOP polimorfik ve şeffaf bir şekilde nesneler oluşturmak için açık bir doğal yol sağlamaz.)

Bu nedenle, çoğu modern OOP dili, onları daha etkileyici ve daha güçlü, aynı zamanda daha karmaşık kılan diğer paradigmaların özelliklerini içerir. Bunun için en önemli örnek C # 'dır: belirgin OOP köklerine sahiptir, ancak delegeler, olaylar, tür çıkarımları, değişken veri türleri, özellikler, adsız işlevler, lambda ifadeleri, jenerikler, vb. Gibi özellikler en çok Fonksiyonel Programlama .


Bu yüzden tasarım desenleri karmaşıklığı ekledi. Anlam tasarım desenleri mutlaka OOP değil, OOP'yi geliştirmek için eklenir.
fasipe fasipe

@tunmisefasipe: Tam değil. Tasarım kalıpları sadece standart sorunların kanıtlanmış çözümleridir; Onlar OOP'a bir addition ek değil ”, sonuçtur. Karmaşıklık zaten oradaydı; tasarım desenleri sadece bununla baş etmek için yemek kitabı stratejileri sağlar.
tdammers

17

Hayır, daha fazla mühendislik çalışması oldu. Ve haklısın, SO C ++ sohbetinde sık sık şaka yapıyoruz, Java kodunda gördüğümüz AbstractSingletonFactoryProxyBeanBridgeAdapterManagers.

Ancak iyi kod bu özelliği sergilemez. Kodda, yine de söyleyebilirsiniz

std::stack<int> s;
s.push(5);
s.pop();

4
Yayınınızdan temizlemek ama aşırı mühendislik Java'nın hem belirgindir düşünmüyorum ve C ++ kodunun. Her iki dilin de kendisi değil, programcıların pratiği olan bir özellik ... Her iki dil de iyi kod yazmaya izin veriyor, ancak her ikisi de (IMO) özellikle onun için uygun değil.
Andres F.

12
Aşırı mühendislik bahsedersek, bu parçacığı zorunludur: discuss.joelonsoftware.com/default.asp?joel.3.219431
Güvenli

3
@AndresF. true, ancak C ++ kodunda çok fazla bir şey görünmüyor, oysa Java ve .NET'te: sadece MVVMVMMD tasarım modeline bakın msdn.microsoft.com/en-us/magazine/hh965661.aspx as 'basit kodu' nasıl aldığınıza bir örnek ve 'kolay' görünmesini sağlamak için üzerine bir tasarım deseni tokatlayın ve ardından tasarım deseni üzerinde başka bir tasarım deseni tokatlayın, çünkü orijinal desen reklamı kadar basit değildi. Aşırı mühendislik gittikçe yaygınlaşıyor.
gbjbaanb

5
"Olmak" biti ile tartışırdım. Aşırı mühendislik, mühendislik kadar eskidir.
Robotu

4
@AndresF. Sohbette özellikle Java karşıtıyız ancak Java'nın C ++ 'dan çok daha fazla mühendisliği teşvik ettiği doğru, çünkü bunu daha uygun fiyatlı (GC) yapıyor ve popüler kurumsal Java kütüphanelerinin belirttiğiniz gibi bu tarzı popülerleştirdi kendin.
Konrad Rudolph

10

Bahsettiğiniz "karmaşıklık" ile ilgili sorunların OOP ile ilgisi olmadığını söyleyebilirim. Endişeleri ayırma ile daha fazla ilgisi var.

Yıllar önce, etki alanı sınıfının kendisini veritabanından yüklemekle yükümlü olduğu bir sistem üzerinde çalıştım, örneğin

var userId = Request.QueryString["UserID"].ToInt();
var user = new User(userId);
user.Name = ...;
...
user.Save();

Bu çok açık kod. Bunu anlamada sorun yok. Ancak sorun, kodu test eden birimde olacaktır. Yani, üniteyi Usersınıfı veritabanından yüklemek zorunda kalmadan nasıl test edebilirim? Ve bu web isteği işleme kodunu veritabanına erişimi olmadan nasıl test edebilirim? Bu sadece mümkün değil.

Bu nedenle, etki alanı mantığını bir kullanıcıdan bir veri deposuna gerçekten yükleme ve kaydetme işlevinden bir kullanıcıya atama sorumluluğunu ayırmak için bir depo gibi bir düzenimiz vardır. IOC kuplajı azaltmada yardımcı olur, ayrıca kodu daha test edilebilir hale getirir, vb.

Peki, yazdığınız örneğe geri dönersek, oluşturduktan sonra hisse senedine ne yapardınız? Veritabanına kaydet

Stock stock = new Stock();
stock.addItem(item);
stock.removeItem(item);
this.StockRepository.Add(stock);

Kırmızı olan! OOP'un ilerlemesinde daha zor olması gerektiğini gösteren hiçbir hareket yoktur. Ne yazık ki, veri erişim kodunuz için bir OR eşleyici kullanmayı seçtiyseniz, OR eşleştiricisinin sisteminizi nasıl yazabileceğinize dair kısıtlamalar getirmesi sorunu ile karşılaşabilirsiniz. Ama bu başka bir konu.

Bu kalıplarda yeniyseniz, yeni bir programlama stili öğrenmeniz gerekebilir. Ancak bu programlama tarzı eski okul OOP programlamasından daha zor değildir.


Deponuzu oluşturmak için harcadığınız çabayı biliyorsunuz. Ayarladıktan sonra, tekrar kullanılabilir hale geldi.
fasipe fason

belki de sorun, birim testleriyle ilgilidir, minik parçalar yerine bütünü test etmek için daha iyi araçlara sahip olsaydık (her neyse gerektiği gibi), daha az böcek içeren sistemlere sahip miyiz?
gbjbaanb

2
@gbjbaanb: zaten buna sahibiz, entegrasyon / fonksiyonel test. Birim testi, farklı ancak eşit derecede gerekli bir amaca hizmet eder
Kevin

@gbjbaanb - Sistem çapında / kabul testi için harika araçlarımız var, örneğin Raylar platformundaki Salatalık. Ancak gerçekten iyi olan ve çok az hata yazan takımlar, aynı zamanda hızlı bir şekilde dağıtan, çok sayıda birim testi ve sadece birkaç sistem çapında test yazan ekipler. "Test üçgeni" konusuna bakın, örneğin burada jonkruger.com/blog/2010/02/08/the-automated-testing-triangle
Pete

4

Ne. Sorunlarımız gerçekten değişmedi; kabul edilebilir kod için çubuk yükseltildi.

Yukarıdakileri elde etmek için birkaç sınıf (örneğin, özet, fabrika, DAO vb.) Oluşturmanız ve birkaç arayüz uygulamanız gerekebilir.

Sen yok olması bunu yapmaya. Fakat eğer o zaman sorun yaşamadığınızda sorunlar ortaya çıkar; her zaman orada olan problemleri. Şimdi olsa da, programcılar bu sorunları tanımlamak ve bunları hafifletmek için mekanizmalar sağlamak için yeterli deneyime sahiptir (gerekirse). Bunlar hakkında daha fazla şey öğreniyoruz ve daha iyi çözümler üretiyoruz (örneğin, örneğin singleton hakkındaki programcıların görüşleri).

Ancak, programcıları OO'ya (veya bu konuda herhangi bir şeyle) tanıtmanın istisnai durumlar üzerinde parlaklık gösterme eğiliminde olacağının farkında olmalısınız. Mutlu yolu anlatmak daha kolay, ve yeni başlayanlar bunu bıraktıktan sonra gerisini merak edin. Gümüş mermi yoktur; böylece evet, işler her zaman olacaktır herhalde görünmek o pastoral sanrı bozulduğunda zor olan ...


3

“OO'ya giriş” örnekleri gerçek dünyadaki uygulamalardan çok daha basittir. Yukarıdakilere ulaşmak için sadece bir sınıfa ihtiyacınız var. Sorun çok fazla yapmamasıdır. Bazı tasarım kalıpları yakınlaşmaya çalışır (ActiveRecord gibi). Ama sonuçta önemsiz olmayan herhangi bir örneğin birden fazla sınıfa sahip olacağı; sorun değil.


Ayrıca, çerçevelerin zaman içinde biriktiğini unutmayın. Yani evet, programlama daha fazla bilgi gerektirir. Aynı zamanda kişinin daha kısa sürede daha fazlasını yapabileceği anlamına gelir.
Jeanne Boyarsky

3

Bugün OO kullanan programlama dilleri değişmeye devam eden karmaşık gereksinimler ve ortamlar için çalışıyor. OO, geliştiricilerin çeşitli karmaşıklık düzeylerini gizlemelerine izin verir (diğer özelliklerin yanı sıra), böylece kodlamanın oluşturulması ve anlaşılması daha kolay hale gelir. Ancak, bu özellik her zaman kutunun dışında değildir. Örneğinizde, OO bir koleksiyondaki öğeleri yönetmek için bir yöntem sağlayarak benden bazı detayları gizlemenize izin verdi ve hatta "AddItem" yöntemini kullanarak devam ettirebilir. Karmaşıklığı gizlemek için çaba harcamak, kullanımı kolay ve hayatı kolaylaştıran yeniden kullanılabilir bir çerçeve ile sonuçlanabilir. Örneğin, birçok ORM uygulaması, programcının SQL ayrıntılarını yazmasına gerek kalmadan veritabanlarıyla iletişim kurmanıza izin verir. Bu gerçekten güçlü ve geliştirici daha basit hale getirir.

Bahsettiğiniz desenler tam da bu. Hayatınızı kolaylaştırmaları gerekiyordu. Ama onları benimsemek ve ayarlamak için size kalmış. Daha fazla çalışmanın gerekli olduğu gerçeği, sadece daha fazla fayda elde etmenizdir. Bir Ferrari için daha fazla ödeme yapmak gibi. Ekstralar istiyorsanız, onlar için para ödersiniz. Bu nedenle, birkaç sunucuda ve farklı arka uç veritabanlarında çalıştırılabilecek ölçeklenebilir bir N-Tier çözümü oluşturmaya karar verirseniz, bunun bir bedeli vardır. Uygulamanız bu karmaşıklığı gerektirmiyorsa, fazladan parçaları görmezden gelin ve ihtiyacınızı karşılayan en basit çözüme geri dönün (KISS & YAGNI).

Bu yüzden, tamamlanmak için, OOP'nin bir kavram olarak kendisinin daha karmaşık hale geldiğini sanmıyorum, biz, OOP kullanıcılarının onu farklı şekillerde kullanma seçeneğine sahip olduğumuzu ve bu iyi bir şey.


Puanları temizle. YAGNI'yi tanıyorum. KISS Nedir?
fasipe fason

2
@tunmisefasipe, KISS bir tasarım prensibi için kısa bir isimdir. Orijinal kelimeler "Basit Tut (Aptal)" dır (ref: en.wikipedia.org/wiki/KISS_principle ), ancak daha kibar bir ifadeyle "Basit Tutun" olabilir.
NoChance

3
@tunmisefasipe - KISS = Basit Tut, Aptal. Kendime OVER, OVER ve OVER olarak tekrarladığım bir cümle ve hala her zaman batıyor gibi görünmüyor.
Michael Kohne

@MichaelKohne, hepimiz biliyoruz! Sanırım işleri basitleştirebilmek bir sanat. E = M C C çok özlü bir biçimde bir sürü söylüyor!
NoChance

3

Kısa Cevap : Evet, çünkü daha zor problemlerle uğraşıyorsunuz.

Uzun Cevap (şiddetle önyargılı) : Benim için tasarım kalıpları genellikle bazı paradigmaların belirli bir alanda sorunları olduğunu gösterir. OOP kalıpları OOP problemleriyle (düşük seviyelerde Java kalıpları Java problemleriyle uğraşır), FP kalıpları FP ile ilgili problemleri çözer.

Programlama sırasında farklı öncelikleriniz olabilir. Doğru bir programa sahip olmak isteyebilirsiniz, piyasaya sürenin kısalması, mümkün olan en hızlı program, uzun vadeli bakım veya yeni bir işe alımla anında bakım yapılabilirlik isteyebilirsiniz. İçinizde bulunduğunuz gürlüğe bağlı olarak, çok farklı olacaksınız - santralin kontrol ünitesini programlıyorsanız, bunu ilk defa doğru yapmak ve şimdi ve her seferinde hata düzeltme yapmak istemiyorsanız ("Her bastığınızda erime oluyor mu Ctrl+Alt+Del?"). Eğer HPC'deyseniz, mantık göreceli olarak basit olabilir, ancak mümkün olduğunca hızlı bir şekilde yürütülmesi istenebilir. Ek olarak, bazı paradigmalar bazı problemlere daha iyi uyar (AI ve mantık programlama, veri ve ilişkisel veritabanları).

OOP, bazı durumlarda basit vakalarda 'çok iyi' olmakta ve “gerçek canlı modelleme” hikayesidir. OOP I hakkında ilk kitapta örnek okumak için orada sınıflar vardı Person, Employeeve Managerile is-ailişkisi. Şimdiye kadar çok iyi ama ya çalışan yöneticiye terfi ettirilirse?

Öte yandan, diğer paradigmaların ilk kez daha zor dersleri vardır - örneğin değişmez değişkenleri olan FP (komik bir şey: programlama konusunda deneyime sahip kişilerin, bunun ilk dil için olanlardan daha öğrenmeyi zor bulmasıdır) - ancak sonuçta onlar OOP'den daha zor değil. Saf fonksiyonların test edilmesi önemsizdir ve Haskell / Scala / ... 'da sizin için testler yapan araçlara sahipsiniz.

PS. Evet - cevap, OOP'a karşı önyargılıdır ve bazılarının OOP'a 'tepki olarak' olduğunu itiraf ediyorum. OOP'un kullanımları var ama bence tek, nihai çözüm değil.

PPS. Evet - tasarım desenlerini kullanın - OOP programlamayı nihayetinde basitleştirir.

Bitki koruma ürünlerinin. OOP'yi zorunlu programlamanın eş anlamlısı olarak kullandım.


2

Daha çok belge ve örneklerin daha gerçekçi hale geldiğini düşünüyorum.

Erken OOP kitapları (özellikle erken Java kitapları), uygulama programlamasının saçma bir şekilde basitleştirilmiş bir görünümünü sundu. "10 satırlık bir Java programı olan bir banka hesabını borçlandırın" örnekleri her zaman özellikle sinir bozucuydu, çünkü bu basit görevin gerçek örneklerini 6000 satır COBOL koduna (ve Java değiştirilmeden önce 3500 satıra çalışmayı denedim) gördüm. Mümkün olduğu gibi!).

Neyse ki OO kitapları şimdi gerçek hayatın karmaşıklığını kabul etme eğilimindedir ve onlarla nasıl başa çıkılacağına dair yararlı örnekler sunar.

Kod sadece 15 hatlarında bir banka hesabı nasıl çalıştırılacağını görmek istiyorsanız Ama fonksiyonel programlama senin adam

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.