Neden OOP için gerekli kavramların tutarlı bir tanımı yok?


12

Programlamaya çok yeniyim ve farklı kaynaklardan farklı sözleşmeleri duymaktan biraz kafam karıştı:

Nesneye yönelik programlamanın 4 veya 5 konsepti var mı?

Yeni gelen biri olarak, bunların 5 kavram olduğunu anlıyorum:

  • Soyutlama
  • miras
  • kapsülleme
  • Polimorfizm
  • Modülarite

Öyleyse neden daha "katı" bir tanım bulamıyorum ve bu kavramların çeşitli düzenlemeleri var gibi görünüyor?


7
Belki de bu matematik gibi değildir (CS'deki bazı kavramlar vardır, ancak bence OOP bu kategoriye ait değildir), bu yüzden başlamak için kesin bir tanım yoktur. Örneğin 'modülerlik' ne kadar önemli? OOP için gerçekten çok özel mi, bundan bahsetmek zorunda mıyız yoksa diğer dördünü doğru bir şekilde uygularsak kendi başına olan bir şey mi olur? Bazı listeler 'hiyerarşi' ekler, ancak bu gerçekten ekstra bir şey mi yoksa kalıtım ve çok biçimlilikten mi kaynaklanıyor?
thorsten müller

6
Tavsiye kelimesi: Çok yeni bir programcı olarak terminoloji ve teoriyi anlamaya bu kadar asılmamalısınız. Öncelikle uygulamalı programlama deneyimi toplayın ve bu insanların ne hakkında konuştukları çok daha açık hale gelecektir.
Philipp

9
Başka bir şey, OOP'un zaman içinde değişmesidir. C ++ günlerinin başlarında çok fazla odaklanma (OOP'un bundan daha ileri gittiğini biliyorum) Kalıtım ve Polimorfizm üzerineydi. Bugünün odak noktası Soyutlama ve Kapsülleme üzerine çok daha fazla.
Bent

3
OO tanımında hassasiyet eksikliği hakkında bazı ilginç tartışmalara buradan ulaşabilirsiniz: c2.com/cgi/wiki?NobodyAgreesOnWhatOoIs
MichelHenrich

Yanıtlar:


26

Nesneye yönelik programlamanın ne anlama geldiğine dair farklı açıklamalar bulmanızın nedeni, evrensel olarak uygulanabilir katı bir tanım formüle etme yetkisine sahip tek bir kişi veya kuruluş olmamasıdır.

Nesneye yönelik programlama bir ISO standardı veya bilimsel bir yasa değildir. Bu bir felsefedir. Ve tüm felsefelerde olduğu gibi, her türlü farklı yorum vardır ve hiçbir yorum evrensel olarak uygulanabilir değildir. Bir yazılım mimarisi tasarlarken hangi kavramları izlemeniz gerektiğini anlatan bir metni okuduğunuzda, bunu yazarın mesleki deneyimleri sırasında oluşturduğu fikirlere dayanan evrensel bir gerçek olarak değil bir kılavuz olarak görmelisiniz.


12

Nesneye yönelik programlamanın 5 veya 4 bileşeni var mı?

Diğerlerinin de belirttiği gibi, "OO" nun gerçekten herhangi bir bileşeni yoktur , çünkü bu, bir araç kiti veya bir dizi açıkça tanımlanmış süreçler değil, sorunlara çözümlerin modellenmesini düşünmenin bir yoludur.

Yeni gelen biri olarak, bunların 5 bileşen olduğunu anlıyorum:

Soyutlama, Kalıtım, Kapsülleme, Polimorfizm ve Modülerlik?

Kalıtım ve Çok Biçimlilik programlama dili özellikleridir. Bunları anlamanız iyi, ancak bunların araç olduğunu unutmayın (yani, diğer araçlarda olduğu gibi, yalnızca belirli sorunları çözmek için kullanılmalı ve amaç veya çabalamak için bir şey olarak ele alınmamalıdır). Bunlardan herhangi birini kullanmadan "OO" kodunu yazabilirsiniz (ve sıklıkla yazmalısınız). Şimdiye kadar gördüğüm en iyi "OO" kodlarından bazıları, kalıtım veya polimorfizmden çok az yararlanıyor.

Soyutlama, Kapsülleme ve Modülerlik, kodla daha az ilgilidir ve bir soruna nasıl baktığınız, o sorunu anlamaya çalıştığınız yol ve koddaki çözümünüzü nasıl tasarladığınız ve yapılandırdığınız hakkında daha fazladır.

Ayrıca, bu tasarım fikirleri "OO" ya özel değildir. Muhtemelen onları şimdi temel bir seviyede anlamış olursunuz, bu da bir ders kitabı mükemmel tanımını açıklayabilmeyi ve biraz önemsiz sorunlara uygulayabilmeyi içerebilir; Her ne kadar daha derin bir anlayış testi çok büyük bir karmaşık soruna ve ne kadar karmaşıklıkla başa çıkabileceğinize rağmen.

Başka bir anlayış testi, bir sorunu çözmek için kullandığınız yaklaşımdır; ve veri modelleme açısından genellikle OO hakkında öğretilen "OO" 'ya yeni gelenler (çünkü çoğu insan bunu 1990'larda tekrar anlardı) ve genellikle bir sorunun yanlış yönlerine odaklanırlar - yani odaklanırlar verilere çok fazla ve davranışa yeterince odaklanmıyorlar.

Örneğin, klasik örnekler sıklıkla gibi kuruluşlara başvurmak Dog, Cat, Elephant, Seagull, Shark, vb genellikle bu tür örneklere bakıp hemen düşün "OO" Yeni Katılanlar "Ah, ben olarak adlandırılan bir baz varlığı gerek Animal" , ve hatta diğer ile sona erebilir her birinde farklı niteliklere sahip, temiz bir miras heirarchy gibi Mammalve Amphibianiçinde ara varlıklar .

Bu düşünme şekli birkaç OO kavramının çok temel bir anlayışını gösterse de, deneyimli bir OO programcısı ona asla bu şekilde yaklaşmaz ve bu sonuca atlamaz (Ve aslında yeterli bilgiye sahip olmadıklarından şikayet ederler), çünkü bu yaklaşım Varlığı gösterir OO modellemesinden ziyade modelleme ve çünkü anlaşmalı örnek bu hayvanların davranışları hakkında hiçbir şey söylemediğinden (Ve birçok insan bu günlerde OO'nun özünün davranış ve işlevsellikte olduğunu iddia eder).

"OO" hakkında bilgi edinme yolu geleneksel olarak, modellemekte olduğunuz sorunun davranışı hakkında hiçbir şey bilmediğinizde (veya çok az) veya dikkatinizi varlıklar yerine odaklama hatasını yaptığınızda yanlış soyutlamaları oluşturmak için zaman harcamayı içerir. işlevselliği, bunun bir parçası olmasına rağmen, yıllar boyunca yazılmış çok sayıda kitap, kurs ve çevrimiçi öğretici (yanlış) öğrenenleri uzun bir süre bu yolda yönlendiriyordu (Gelgit değişiyor).

Genel olarak, anlayışınızın çoğu deneyime inecektir. Şimdiye kadar öğrendiğiniz kavramlar iyi bir başlangıç, yol boyunca öğrenmeniz gereken daha fazla kavram var (örneğin, "KATI" ve "KURU" ilkeleri) ve uzun süre harcamak zorunda kalacaksınız. teori gerçekte oldukça karmaşık problemlerle uygulamaya koyulmadan önce, tüm bunların yerine "tıklanması" muhtemeldir.


2
Bir köpekbalığı ve kurbağa her ikisi de yüzüyor, ancak biri balık, diğeri amfibi. Bence bu örnek sizin amacınızı iyi açıklıyor.
RubberDuck

10

"Nesne Yönelimi" terimi Dr. Alan Kay tarafından üretilmiştir, bu yüzden ne anlama geldiğine dair yetkili kaynaktır ve onu şöyle tanımlar :

OOP bana sadece mesajlaşma, yerel tutma ve devlet sürecinin korunması ve gizlenmesi ve her şeyin aşırı geç bağlanması anlamına geliyor.

Bunu parçalayalım:

  • mesajlaşma (Smalltalk'a aşina değilseniz "sanal yöntem dağıtımı")
  • devlet süreci
    • yerel olarak muhafaza edildi
    • korumalı
    • gizli
  • her şeyin aşırı geç bağlayıcılığı

Uygulama açısından, mesajlaşma geç bağlı bir prosedür çağrısıdır ve prosedür çağrıları geç bağlıysa, tasarım zamanında ne arayacağınızı bilemezsiniz , bu nedenle devletin somut temsili hakkında herhangi bir varsayım yapamazsınız. Yani, gerçekten mesajlaşma ile ilgili, geç bağlama mesajlaşma uygulamasıdır ve kapsülleme bunun bir sonucudur.

Daha sonra " Büyük fikir" mesajlaşma " olduğunu açıkladı ve" mesaj yönelimli "yerine" nesne yönelimli "olarak adlandırdığı için pişmanlık duydu, çünkü" nesne yönelimli "terimi önemsiz şeye odaklanıyor (nesneler) ) ve gerçekten önemli olandan (mesajlaşma) dikkat dağıtır:

Smalltalk'un sadece sözdizimi ya da sınıf kütüphanesi olmadığını, hatta sınıflarla ilgili olmadığını herkese hatırlatmak için son OOPSLA'da bazı acıları aldığımı nazik bir hatırlatma. Uzun zaman önce bu konu için "nesneler" terimini bulduğum için özür dilerim, çünkü birçok insan daha az fikre odaklanıyor.

Büyük fikir "mesajlaşma" - Smalltalk / Squeak çekirdeği bununla ilgilidir (ve bu Xerox PARC aşamasında asla tam olarak tamamlanmamış bir şeydir). Japonların küçük bir sözcüğü vardır - ma - "arasında" olan - belki de en yakın İngilizce karşılığı "geçiş reklamı" dır. Büyük ve büyütülebilir sistemler üretmenin anahtarı, modüllerinin iç özelliklerinin ve davranışlarının olması gerekenden ziyade nasıl iletişim kurduğunu tasarlamaktır. İnterneti düşünün - yaşamak için, (a) herhangi bir standardın ötesinde birçok farklı türde fikir ve gerçekleştirmeye izin vermek ve (b) bu ​​fikirler arasında değişen derecelerde güvenli birlikte çalışabilirliğe izin vermek zorundadır.

(Elbette, bugün çoğu insan nesnelere değil, daha da yanlış olan sınıflara odaklanıyor.)

Mesajlaşma , hem metafor hem de bir mekanizma olarak OO için esastır .

Birisine mesaj gönderirseniz, onunla ne yaptığını bilmezsiniz. Gözleyebileceğiniz tek şey onların cevabıdır. İletiyi kendileri işleyip işlemediklerini (yani nesnenin bir yöntemi varsa), iletiyi başka bir kişiye iletmişlerse (temsilci / proxy), anladılar bile. Enkapsülasyonun hepsi bu, OO tamamen bununla ilgili. Proxy'yi gerçekte nasıl beklediğinize yanıt verdiği sürece gerçek şeyden ayıramazsınız.

"Mesajlaşma" için daha "modern" bir terim, "dinamik yöntem dağıtımı" veya "sanal yöntem çağrısı" dır, ancak bu metaforu kaybeder ve mekanizmaya odaklanır.

Yani, Alan Kay'ın tanımına bakmanın iki yolu vardır: eğer kendi başına ayakta durursanız, mesajlaşmanın temelde geç bağlı bir prosedür çağrısı olduğunu ve geç bağlama kapsülleme anlamına geldiğini gözlemleyebilirsiniz, böylece # 1 ve # 2 aslında gereksizdir ve OO tamamen geç bağlama ile ilgilidir.

Ancak, daha sonra önemli olanın mesajlaşma olduğunu açıkladı ve böylece farklı bir açıdan bakabiliriz: mesajlaşma geç bağlı. Şimdi, eğer mesajlaşma mümkün olan tek şey olsaydı, o zaman # 3 önemsiz doğruydu: sadece bir şey varsa ve bu şey geç bağlıysa, o zaman her şey geç bağlı. Ve bir kez daha, kapsülleme mesajlaşmadan kaynaklanıyor.

Benzer noktalar William R. Cook tarafından tekrar gözden geçirilen Veri Soyutlamasını Anlama ve ayrıca "Nesne" ve "Nesneye Yönelik" Modern Tanımlar Önerisinde de yer almaktadır .

İşlemlerin dinamik gönderimi, nesnelerin temel özelliğidir. Bu, çağrılacak işlemin nesnenin dinamik bir özelliği olduğu anlamına gelir. İşlemler statik olarak tanımlanamaz ve genel olarak, belirli bir isteğe yanıt olarak hangi işlemin çalıştırılacağı dışında, çalıştırılması dışında hiçbir yol yoktur. Bu, her zaman dinamik olarak gönderilen birinci sınıf işlevlerle tamamen aynıdır.

Smalltalk-72'de herhangi bir nesne bile yoktu! Yalnızca ayrıştırılan, yeniden yazılan ve yeniden yönlendirilen mesaj akışları vardı . İlk önce yöntemler (mesaj akışlarını ayrıştırmak ve yeniden yönlendirmek için standart yollar), daha sonra nesneler geldi (bazı özel durumları paylaşan yöntem grupları). Miras çok sonra geldi ve sınıflar sadece mirası desteklemenin bir yolu olarak tanıtıldı. Kay'ın araştırma grubu prototipleri zaten biliyor olsaydı, muhtemelen ilk etapta hiç ders vermezlerdi.

Türler ve Programlama Dillerinde Benjamin Pierce , Nesne Yönelimi'nin tanımlayıcı özelliğinin Açık Özyineleme olduğunu savunmaktadır .

Alan Kay'a göre OO tamamen mesajlaşma ile ilgili. William Cook'a göre, OO tamamen dinamik yöntem dağıtımı ile ilgilidir (ki bu gerçekten aynı şeydir). Benjamin Pierce'a göre, OO tamamen Açık Özyineleme ile ilgilidir, bu temel olarak öz referansların dinamik olarak çözüldüğü (veya en azından bu düşünmenin bir yolu) veya başka bir deyişle mesajlaşma anlamına gelir.

Gördüğünüz gibi, "OO" terimini icat eden kişi nesneler üzerinde oldukça metafizik bir görüşe sahiptir, Cook oldukça pragmatik bir görüşe sahiptir ve Pierce çok titiz bir matematiksel görüşe sahiptir. Ama önemli olan şudur: filozof, pragmatist ve teorisyen aynı fikirde! Mesajlaşma OO'nun tek direğidir. Dönemi.

Burada kalıtımdan bahsedilmediğine dikkat edin! Kalıtım OO için gerekli değildir. Genel olarak, çoğu OO dilinin yeniden kullanım için bir yolu vardır, ancak bunun kalıtım olması gerekmez. Örneğin bir çeşit heyet de olabilir. Aslında, Orlando Antlaşması tartışır heyeti miras alternatif ve farklı nesne oiented dillerin tasarım alanı içinde farklı tasarım noktalarına heyet ve miras kurşun formları olarak. (Aslında Java gibi kalıtımı destekleyen dillerde bile, insanlara bundan kaçınmayı öğrettiklerini, yine OO için gerekli olmadığını belirttiklerini unutmayın.)


1
@DavidArno Yorumunuz hiç de yapıcı değil. Alan Kay, bu kavram için "nesne" terimini icat ettiğini iddia ediyor (sanırım, kavramın kendisi değil). Konuyla ilgili tanınmış bir otorite ile çelişecekseniz, en azından daha yapıcı bir yorum yazın.
Andres

1
@DavidArno Ayrıca, downvote sizin mi? Birisi, tanınmış uzmanlardan OOP'nin ne anlama geldiğine dair farklı görüşlerin kapsamlı bir listesini yazmak için zaman ayırdı ve tek bir cümleyle aynı fikirde olmadığınız için bunu düşürdünüz? Oookay.
Andres

2
@AndresF. Bu cevap "Alan Kay ve diğer herkesin iki okulu var. Bu yetki yanılgısına cevap çağrısında bulunuyor. Böylece aşağı oy.
David Arno

2
Aslında bu cevap "olduğu gibi özetlenebilir üç herkesle üç tamamen farklı açılarda ve kimse etmiyorsa gelen düşünce okulları, aslında, onlar anlaşma hepsi." Dilbilimsel kuralcı, Alan Kay terimi icat etti, ne demek istediğini söyler ve mesajlaşma demek olduğunu söylerdi. Dilsel tanımlayıcı, hayır, Alan Kay hiçbir şey söylemez, terimin gerçekten nasıl kullanıldığına bakmalıyız ve Cook'un yaptığı şeydi: OO (Java, C ++) olarak bilinen hangi dilleri inceledi , C #, vb.) Ortak bir noktaya
sahipti

3
tek şey: messaging.He ne yaygın olarak tarif diller okudu değil sahip OO yaygın OO olarak nitelediği dilleri eksiktir, o da bir şey buldum: mesajlaşmayı. Fildişi kule teorisyeni λ-hesabını alır ve genellikle OO olarak tanımlanan bir şey elde etmek için eklenmesi gereken en küçük özellik kümesine bakar ve temelde mesajlaşma için yapı taşı olan açık özyineleme ile gelir. .
Jörg W Mittag

3

@Philipp'in belirttiği gibi, sorunun kökü, bir programlama dilini nesneye yönelik yapan şeyin resmi bir tanımı olmamasıdır. Gerçekten de, bu muhtemelen iyi bir şeydir. Her birinin kendi avantajları ve dezavantajları olan OO programlamayı desteklemenin birçok yolu vardır. Hangi dillerin daha "saf OO" olduğu üzerine tartışma pek bir şey yapamaz.

Ancak, listelediğiniz 5 özelliğe baktığımda, Modülerlik kesinlikle garip olanı. Modülerlik gerçekten bir programlama dili değil, bir programın özelliğidir. Dil düzeyinde, öznitelik "modülerleştirme desteği" dir ve bu tipik olarak bir "modüller" pr "paketleri" mekanizması biçimindedir.

Ancak Modülerliğe gerçek itirazım, Arketipik programlama dili Smalltalk-80'in modülleri desteklemediği ölçüde OO programlama veya OO programlama dilleri için anahtar olmamasıdır. Ve bunu düşündüğünüzde, yaygın olarak kullanılan birçok OOPL'deki modüller için dil desteği "zayıf" tır.

Modüller, kod tabanınızın tek bir kişinin tam olarak anlayamayacağı kadar büyük hale geldiği "büyük programlamayı" desteklemek için tasarlanmıştır. Kodunuzu modüle etmek için programlama dilinde modüllere ihtiyacınız yoktur .


Ben de diğer 4 özellik hakkında tartışmaya girmiyorum ve (örneğin) hangi "kalıtım" modellerinin saf OO olup olmadığı hakkında konuşmuyorum. Ayrıca Alan Kay, OO programlamasını icat ettiğinden dolayı, OO / ve OOPL tanımlarının öncelikli olduğu anlamına gelmez. Açıkçası, durum böyle değil. O ise bir yetkili bir kaynak, ancak (pratikte) daha fazla ağırlık taşıdıkları OO & OOPLs diğer tanımlamalar vermek başka kaynaklar da vardır.


2
+1 Modülerlik, kullanılan programlama diline ve paradigmasına bakılmaksızın, çoğu yazılım sisteminin arzu edilen bir özelliği olarak geniş çapta kabul edilmektedir. OO olmayan birçok dilde modülerleştirme desteği vardır.
Andres

+1 @AndresF. yorum Yap. Gerçekten de, "yapılandırılmış programlama" ve "adım adım ayrıntılandırma" (kod yapısını düşünmek için bir teknik), "daha da kötü yazılımlarla sonuçlanan karmaşıklığın artması" potansiyelinden ortaya çıkar. COBOL'dan önce olsaydı, dilin bu kadar olumsuz bir itibarı IMHO olmazdı. OO'yu pragmatik olarak daha üst düzey bir yapı olarak görüyorum. Ve altta yatan yapı OO olmadan w / kötü COBOL daha iyi değildir demek istiyorum.
radarbob
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.