OOP neden zor? [kapalı]


91

Nesne yönelimli bir dil kullanmaya başladığımda (Java) hemen hemen "Cool" kullandım ve kodlamaya başladım. OOP ile ilgili pek çok soru okuduktan sonrasına kadar bunu hiç düşünmedim. Aldığım genel izlenim, insanların bununla mücadele ettiğidir. Bu kadar zor düşünmedim ve herhangi bir dahi olduğumu söyleyemem, bir şeyi kaçırdığımı veya yanlış anladığımı düşünüyorum.

OOP'yi anlamak neden zor? bunu anlamak zor?


72
Buna karşı koyuyorum: Anlaşılması zor değil, sadece ustalaşması zor. Bir bütün olarak programlama bu şekildedir.
Steven Evers

2
umm değil mi? Belki program bulamayan programcılar, kod satırları yerine hata ayıklamalarını zor buluyorlar mı? bilmiyorum ama kimsenin anlamanın zor olduğunu söylediğini duymadım. Ancak, ppl'nin işlevselliğin tuhaf olduğunu, özellikle değişkenlerinin değerini değiştiremediği için çok garip olduğunu gördüm.

5
@ acidzombie42: İşlevsel hiç de garip değil. RAM'deki bir konumu temsil eden değişkenlerin içeriğini değiştirmek için bir komut listesi yazmanıza gerek yoktur. değişkenler değerleri temsil eder, değerleri değiştirmezsiniz; 42, 42, x, x, - x, her ne ise, kalır. parametrelerini eşleştiren işlevleri sonuçlara yazarsınız. değerler şunlardır: sayılar, değer listeleri, değerlerden değerlere kadar işlevler, yan etkiler üreten programlar ve yürütmede sonuçta ortaya çıkan değerler ve diğerleri. Bu şekilde, ana fonksiyonun sonucu derleyici tarafından, yani çalıştırılabilecek olan program tarafından hesaplanır.
comonad

5
Son zamanlarda Haskell'i öğreniyorum. İşlevsel programlama hakkında ne kadar çok şey öğrenir ve anlarım, OOP'yi o kadar zor hissediyorum. Bunun temel nedeni OOP'un verileri (nesne / sınıf), üzerinde çalışan işlevle (yöntem) birlikte bağlamaya çalıştığını düşünüyorum. Bu sorunun kaynağı ve pek çok OOP tasarım modeli, verileri ve işlevleri birbirine bağlamaktan kaçınmak için tasarlandı. Örneğin, fabrika düzeni, yapıcıyı (bir işlevdir) üzerinde çalıştığı asıl nesneden ayırmak için kullanılır.
ming_codes

1
Çünkü yanlış adlandı. Gerçekten de Konu yönelimli programlama olmalı, bu Konunun Eylemi gerçekleştirmesi (fiil) ve Nesne Eylemi alır - John topu attı. Yani johnsBall.throw () gerçekten mantıklı değil.
Chris Cudmore

Yanıtlar:


119

Ben şahsen OOP mekaniğini kavramak oldukça kolay buldum. Benim için zor kısmı "nedeni" idi. İlk maruz kaldığımda, bir problem arayışında bir çözüm gibiydi. İşte çoğu insanın zor bulmasının birkaç nedeni var:

  1. IMHO OO'yu baştan öğretmek korkunç bir fikir. Prosedürel kodlama "kötü bir alışkanlık" değildir ve bazı işler için doğru araçtır. Bir OO programındaki bireysel yöntemler, her nasılsa, oldukça usule uygun görünme eğilimindedir. Ayrıca, prosedürel programlamayı öğrenmeden önce, sınırlamaları görünür hale gelmesi için yeterince iyi, OO öğrenci için pek kullanışlı görünmüyor.

  2. OO'yu gerçekten anlayabilmeniz için, veri yapılarının temellerini ve geç bağlama / yüksek dereceli işlevleri bilmeniz gerekir. Sadece ilkelleri kullanmak ve daha üst düzey fonksiyonlar etrafında dolaşmak yerine veri yapılandırma kavramlarını bile anlamadıysanız (temelde bir göstergenin verilere ve bir veri üzerinde çalışan fonksiyonların bir demetine geçirilmesi) polimorfizmini bulmak zordur. işaretçilere işlevler.

  3. Tasarım kalıpları, OO için temel bir şey olarak öğretilmeli, daha gelişmiş bir şey değil. Tasarım desenleri, ormanı ağaçların arasından görmenize yardımcı olur ve OO'nun gerçek sorunları basitleştirebileceği yerlere nispeten somut örnekler verir ve nihayetinde onları öğrenmek isteyeceksiniz. Ayrıca, bir kez gerçekten OO aldığınızda, çoğu tasarım deseni görüntünün sonunda belirginleşir.


5
Müthiş cevap, özellikle 1 numara. Tabii ki OO'daki yöntemler, prosedürel bir dilde bulunan yöntemlere benziyor, ancak şimdi onlar da durumu olan nesnelerde barındırılıyor.
Dan Rosenstark

3
Özellikle 1. ve 3. puanlarınızı beğeniyorum. Arkadaşım tasarım kalıpları için gaga, ve ona sadece iyi OOP kullanıyorsanız, çoğunun ilk problemden çok doğal olarak kaynaklandığını söylüyorum.
CodexArcanum

7
+1 "Benim için zor kısım" neden "idi. Dilin temellerini (enkapsülasyonu) ve tasarım ilkelerini ve yeniden yapılanma yöntemlerini, ortak çözümlere (tasarım kalıpları) doğru anlamak ve uygulamak biraz zaman alır.
Belun

12
# 1 ile aynı fikirdeyim, öğrenim sırasında yaptığımdan daha prosedürel bir şekilde nasıl programlandığını bilen insanlara OO'yu açıklamak için daha iyi bir iş yapmanız gerektiğine dair ihtirasına katılıyorum. Hayır, Catmiras alan bir sınıftan bahsetmek Mammal, prosedürel olarak yazdığımız gerçek bir programdan gerçek bir örnek kullanmak yararlı veya bilgilendirici değildir . Basit bir veri yapısı gibi.
Carson63000,

4
-1 Tasarım kalıpları bugün çok fazla vurgulanıyor. Önemli, elbette, ancak: ilk olarak, tüm paradigmalar için önemlidir: işlevsel, yapılandırılmış, hem de OO; ikincisi, paradigmanın bir parçası değil, sadece diğerleri gibi kullanabileceğiniz uygun bir eklenti değiller. @SoftwareRockstar bu cevabı güzel anlatıyor.
CesarGon

56

Bence henüz bahsedilmemiş birkaç faktör var.

Her şeyden önce, en azından her şeyin bir nesne olduğu "en azından OOP" da (örneğin, Smalltalk) , zihninizi zeki bir nesne olarak zekice bir nesne olarak düşünmek için zihninizi doğal olmayan bir konfigürasyona çevirmeniz gerekir sadece bir değer - gerçekte bu yana, 21(örneğin) gerçekten olan bir değer. Bu, özellikle bir yandan OOP'nin büyük bir avantajının gerçeği daha yakından modellediği söylendiğinde sorunlu hale geliyor, ancak LSD'den ilham alan en basit ve en açık kısımlarının bile berbat göründüğü bir şeyi alarak başlıyorsunuz. gerçeklik.

İkincisi, OOP'deki kalıtım, çoğu insanın zihinsel modellerini de çok yakından takip etmiyor. Çoğu insan için, şeyleri en spesifik olarak sınıflandırmak , işe yarayan bir sınıf hiyerarşisi oluşturmak için gereken mutlak kurallara yakın hiçbir yere sahip değildir . Özellikle, class Dbaşkalarından miras kalan bir yaratma class B, nesnelerin class Dkesinlikle, kesinlikle tüm özelliklerini paylaşması anlamına gelir class B. class Dkendine özgü yeni ve farklı özellikler ekleyebilir, ancak tüm özellikleri class Bbozulmadan kalmalıdır.

Aksine, insanlar bir şeyi zihinsel olarak sınıflandırdıklarında, genellikle daha gevşek bir model izlerler. Örneğin, eğer bir kişi bir nesne sınıfını neyin oluşturduğu hakkında bazı kurallar koyarsa, yeterince başka kurallar izlendiği sürece neredeyse herhangi bir kuralın ihlal edilebileceği oldukça tipiktir. Gerçekten kırılamayan birkaç kural bile, neredeyse her zaman bir miktar “gerilebilir”.

Örneğin, “araba” yı sınıf olarak düşünün. Çoğu insanın "araba" olarak düşündüklerinin büyük çoğunluğunun dört tekerleğe sahip olduğunu görmek oldukça kolaydır . Ancak çoğu insan, sadece üç tekerlekli bir araba gördü (en azından bir resmini). Doğru yaştan birkaçı da 80'lerin başından (ya da öylesine) altı tekerleği olan bir yarış arabasını ya da iki tanesini hatırlıyoruz. Bu bize temel olarak üç seçenek sunar:

  1. Bir arabanın kaç tekerleği olduğuna dair hiçbir şey iddia etmeyin - ancak bu her zaman 4 olacağı varsayımına ve başka bir numara için kırılması muhtemel kodun açıklanmasına yol açar.
  2. Tüm arabaların dört tekerleğe sahip olduğunu kabul edin ve gerçekte olduklarını bilmemize rağmen diğerlerini "otomobil değil" olarak sınıflandırın.
  3. Sınıfı, sadece bu sayede ihtiyaç duyulmayacak, kullanılmayacak veya uygun şekilde test edilmeyecek iyi bir şans olsa bile, tekerlek sayısındaki değişime izin verecek şekilde tasarlayın.

OOP hakkında eğitim vermek çoğu zaman muazzam taksonomiler inşa etmeye odaklanır - örneğin, dünyadaki bilinen tüm yaşamın dev bir hiyerarşisinin ne olacağının parçaları veya parçaları. Bu iki problem ortaya çıkarır: her şeyden önce, birçok insanı, eldeki soru ile tamamen alakasız olan büyük miktarlarda bilgiye odaklanmaya yöneltir. Bir noktada, köpek ırklarının nasıl modelleneceği ve (örneğin) "minyatür kanişlerin" "tam boyutlu kanişlerden" mi kalması gerektiği veya bunun tersi mi yoksa soyut bir taban "Kanişlerin mi olduğu konusunda oldukça uzun bir tartışma gördüm. "sınıf," tam boyutlu kaniş "ve" minyatür kaniş "ile ondan hem miras kalan. Hepsinin görmezden geldiği görülüyordu ki, başvurunun köpekler için lisansları takip etmekle ilgilenmesi gerekiyordu.

İkincisi ve neredeyse en önemlisi, eldeki görev için önemli olan özelliklere odaklanmak yerine, öğelerin özelliklerine odaklanmaya yol açar. Şeyleri olduğu gibi modellemeye yönlendiriyor, nerede (çoğu zaman) gerçekte ihtiyaç duyulan şey ihtiyaçlarımızı dolduracak en basit modeli oluşturmak ve yaptığımız soyutlamaya uyması için gerekli alt sınıflara uymak için soyutlamayı kullanmak.

Sonunda bir kez daha söyleyeceğim: yıllar içinde veritabanlarının izlediği aynı yolu yavaşça takip ediyoruz . Erken veritabanları hiyerarşik modeli takip etti. Yalnızca verilere odaklanmaktan başka, bu tek mirastır. Kısa bir süre boyunca, birkaç veri tabanı ağ modelini izledi - temelde çoklu kalıtım ile aynı (ve bu açıdan bakıldığında, çoklu arayüzler farketmek veya ilgilenmek için çoklu temel sınıflardan yeterince farklı değil).

Uzun zaman önce, ancak, veritabanları büyük ölçüde ilişkisel modelde birleşti (ve SQL olmasalar bile, bu soyutlama seviyesinde mevcut "NoSQL" veritabanları da ilişkiseldir). İlişkisel modelin avantajları, onları burada tekrar etmekten zahmet etmeyeceğim yeterince iyi bilinmektedir. Programlamada sahip olduğumuz ilişkisel modelin en yakın analoğunun jenerik programlama olduğunu not edeceğim (ve üzgünüm, fakat ismime rağmen, Java jenerik, örneğin, gerçekten küçük bir adım olsalar bile) doğru yön).


Çok iyi bir şekilde belirtilmiş ve özellikle size verdiğiniz OOP ile ilgili sorunların çoğunun, yeni başlayanlar için sorun değil, genel olarak OOP programcılarının çoğu hakkında düşünmeyi öğrendikleri konulardır. Son zamanlarda bir bileşen modelin çok iyi çalıştığı, hiyerarşik değil, ilişkisel modeller kavramını yakından izleyen oyun tasarımıyla çalışıyorum.
CodexArcanum

7
Geçen gün bunu düşünüyordum. OOP hakkında okuduğum ilk öğrenim materyalinin mirasa odaklandığı görülüyor. Deneyimim gittikçe daha fazla, mirasın çoğunlukla zararlı olmadıkça yararsız olduğunu söylüyor.
rmac 1910'da

Tablo Odaklı Programlama gibi gözükse de, OOP'un yazılım geliştirmenin gümüş mermisi olmadığını daha fazla farkettim diyeceğim.
OnesimusUnbound

1
@OnesimusUnbound: Aradaki fark, jenerik programlamanın bir şeyi yapmanın gerçek ve pratik bir yoludur; masaya dayalı programlama çoğunlukla bir şeyin nasıl işe yarayacağına dair bir teori hakkında çılgınca bir şeydir (TopMind'in comp.object'deki eski yayınlarını okuyunuz ve sen ne demek istediğimi göreceğim - aslında, mesajların hepsi eski olmayabilir; bildiğim kadarıyla bugün bile devam ediyor).
Jerry Coffin,

3
Bu yüzden arayüzler çok iyi. Miras modellemesini alıp birinci sınıf bir yaklaşıma dönüştürüyorsunuz. Örneğin, köpek örneğinde, her köpeğin belirli bir cins için bir cins ve en fazla iki süper türe (her ebeveyn için bir tane) sahip olduğu varsayılabilir. Ayrıca özellikleri içeren bir liste özelliği de olabilir, ancak olası çeşitlilik onları belli bir yapıya sokmayı anlamsız kılar. Özellikleri taramak ve bu sonuçlara dayanarak benzer ırkları birleştirmek için derin bir arama uygulamak daha iyidir.
Evan Plaice

26

OOP soyut düşünme yeteneğini gerektirir; gerçekten de pek az insanın, hatta profesyonel programcının sahip olduğu bir hediye / lanet.


35
Tüm programlama soyut.
JeffO 13 Kasım’da

28
@Jeff O - Ben katılmıyorum. Programlama sadece birisine adım adım nasıl bir şeyler yapılacağını söyleyebilme becerisini gerektirir. Birine fıstık ezmeli ve reçelli sandviç yapmayı söyleyebilirseniz, komutları bir programlama arayüzüne yazabilirsiniz. Bu ap, b & j sandviçinin soyut modellenmesinden ve dünya ile nasıl etkileşime girdiğinden tamamen farklı bir beceridir.
John Kraft

16
Birine 2 kurşun kalem vermek ve sonra onlara 1 kurşun kalem vermek ve kaç tane kalemleri olduğunu sormak somuttur. 2 + 1 = 3 soyut.
JeffO

17
Jeff ile aynı fikirdeyim. Programlama temel olarak soyutlamaları yönetmektir. En azından bu, en temel program akışından başka bir şey için geçerlidir (çünkü her şey soyutlamalar olmadan çok karmaşık olacaktır). Aceminin soyutlamaları nasıl kontrol edeceğini öğrendiği zaman programlamayı öğrenmede belirgin bir aşama var. Bu tarif metaforunun düşeceği yer. Programlama, pişirme gibi bir şey değildir ve bireysel bir algoritma bir tarife benzetilebilirken, programlama temel olarak izole edilmiş algoritmaları uygulamaktan farklıdır.
Konrad Rudolph 16

2
@KonradRudolph Harika bir nokta. "Geri kalan her şey soyutlamalar olmadan çok karmaşık olacak" için +1 .
Karthik Sreenivasan

21

Bence temel zorlukları bu şekilde özetleyebilirsiniz:

// The way most people think.
Operation - object - parameters
// Example:
Turn the car left.

// The way OOP works conceptually
Object - operation - parameters
// Example:
Car.Turn(270);

Elbette, insanlar “sol” un eşleştirilmesine 270 olarak alışabilirler ve evet, “araba çevir” yerine “Car.Turn” diyerek çok büyük bir sıçrama olmaz. AMA, bu nesnelerle iyi başa çıkmak ve onları oluşturmak için normal olarak düşündüğünüz şekilde tersine çevirmelisiniz.

Bir nesneyi değiştirmek yerine, nesneyi aslında kendi kendine yapmasını söylüyoruz. Artık zor hissetmeyebilir, ancak bir pencerenin kendisini açmasını söylemek garip geliyor. Bu şekilde düşünmeyen insanlar, sonunda bir şekilde doğal hale gelinceye kadar bu tuhaflıkla tekrar tekrar mücadele etmek zorundadır.


7
İyi fikir Bence asıl sorun, gerçek hayatta, diğer nesnelerle ilgili olmayan bir “nesne” nin yapabileceği bir şey olmadığıdır. OO, nesnelerin içsel durumlarını değiştirmeleri söylendiği sürece iyi çalışır: rectangle.enlarge (margin_in_pixels), ancak sınırları yıllar önce fark ettim. Bir gün programcılar donanım takıyorduk. Birisi "screw.turn" tarardı Komik iki nesne de görevi kendisi yapamaz. OO yeterince iyi değil.
DarenW

3
+1, yıllar sonra "substr (tarih, 0,4)" yazdıktan sonra, "date.substring (0,4)" yazmak zor
ern0

4
Kod snippet'i için +1. Gerçek bir düşünce sürecini açıkça gösteriyor.
Karthik Sreenivasan

2
Aslında gönderdiğiniz bir komut olarak okurdum. "Arabaya sola dönmesini söyle" gibi. Oop nesnelere mesaj yollamaya dayanıyordu, bu yüzden yorumlayacağım.
bunglestink

1
İyi içgörü, öyleyse mayıs OOP "ajan sistemlerinin" modellenmesi için daha uygun mu?
Qbik

21

Herhangi bir paradigma, çoğu insan için, kavramak için "kenardan" belirli bir itme gerektirir. Tanım olarak, bu yeni bir düşünce tarzıdır ve bu nedenle, yeni fikirlerin neden yararlı olduğunu tam olarak kavramak ve yeni fikirlerin neden tamamen anlaşılmasını sağlamak gerekir.

Bence problemin çoğu, bilgisayar programlamayı öğretmek için kullanılan yöntemlerin genel olarak oldukça zayıf olmasıdır. OOP, o kadar yaygındır ki, o kadar belirgin değildir, ancak onu hala işlevsel programlamada görüyorsunuz:

  • önemli kavramlar garip isimlerin arkasına gizlenmiştir (FP: Monad nedir? OOP: Neden onları bazen işlevler olarak adlandırıyorlar?

  • garip kavramlar gerçekte ne yaptıkları ya da neden kullandıklarını ya da neden herhangi birini kullanmayı düşündükleri yerine metaforda açıklanmaktadır (FP: Bir monad bir uzay giysisidir, bazı kodları sarar. OOP: An nesne bir ördek gibidir, gürültü yapabilir, yürüyebilir ve Hayvan'dan miras alabilir)

  • iyi şeyler kişiden kişiye değişir, bu nedenle herhangi bir öğrencinin bahşiş noktası ne olacağı açık değildir ve çoğu zaman öğretmen bile hatırlayamaz. (FP: Oh, monadlar, türün içindeki bir şeyi gizlemenizi ve her seferinde olanları açıkça yazmanıza gerek kalmadan devam ettirmenizi sağlar. OOP: Ah, nesneler, bu verilerle bir tür veri için işlevleri korumanıza izin verir.)

En kötüsü, sorunun belirttiği gibi, bazı insanlar derhal kavramın neden iyi olduğunu anlamaya başlayacaklar, bazıları ise işe yaramayacak. Bu gerçekten devrilme noktasının ne olduğuna bağlı. Benim için, nesnelerin veri depoladığını ve bu veriler için kullanılan yöntemlerin anahtar olduğunu biliyordum, ondan sonra her şey doğal bir uzantıya uyuyordu. Sonra bir nesneden bir yöntem çağrısının ilk parametre olarak bu nesne ile statik bir çağrı yapmaya çok benzer olduğunun farkına varmak gibi sıçradım.

Küçük atlayışlar daha sonra anlayışı iyileştirmeye yardımcı olur, ancak bir kişiyi "OOP mantıklı değil, insanlar bunu neden yapıyor?" Dan alan ilk başlangıçtır. "OOP en iyisidir, neden insanlar başka bir şey yapıyor?"


8
Özellikle metaforizmadan nefret ediyorum, çoğu kez değil, tarif etmek yerine kafasını karıştırıyorlar.
Yalan Ryan

3
"Sonra bir nesneden bir yöntem çağrısının ilk parametre olarak bu nesne ile statik bir çağrı yapmaya çok benzer olduğunu fark etmek gibi daha sonra atlamıştım." Python gibi dillerde olduğu gibi, baştan daha fazla vurgulanmasını diliyorum.
Jared Updike

1
Kavramları açıklamak için metafor kullanmakla ilgili sorunum, öğretmenin genellikle metaforda durduğu, sanki her şeyi açıklıyor gibi. Hayır, bu tam bir açıklama değil; bu sadece kafalarımızı asıl açıklamanın etrafına sarmamıza yardımcı olacak bir örnek .
15'te atıyor

Mükemmel cevap! OOP'yi anlamadaki ilk adımın, vakfın iyi bir şekilde anlaşılmasıyla birlikte doğal uzantılardan sonra gelenlerden daha önemli olacağını açıklamak için +1. : D
Karthik Sreenivasan

"sıçrama" öğrenimindeki dittos: OOP'u "sadece" modüler / yapılandırılmış / kademeli yapı olarak değil, steroidler olarak algılamaya başladığımda; bazı çok eski ve karışık ve sürdürülemezliğin ötesinde bir COBOL programı yazdım. COBOL'un küresel kapsamı, OO prensiplerini esasen özel kayıt yapıları, tek amaçlı değişkenler ve sıkıca odaklanmış, modüler ve yapılandırılmış paragraflar (yöntemler) ile uyguladım.
radarbob

15

Çünkü OOP'nin temel açıklaması, alanda nasıl kullanıldığı ile çok az ilgisi var. Öğretmek için programların çoğu, "Bir arabayı bir nesne olarak düşün, fiziksel olarak tekerlekleri ve kapılar, ve şanzıman ..." gibi fiziksel bir model kullanmaya çalışır, ancak bazı karanlık simülasyon programları dışında, nesneler fiziksel olmayan kavramları temsil etmek veya dolaylı yüklemeyi tanıtmak için daha sık kullanılır. Etki, insanların sezgisel olarak yanlış bir şekilde anlamalarını sağlamasıdır.

Tasarım modellerinden ders vermek OOP'yi tanımlamak için daha iyi bir yoldur, çünkü programcılara bazı gerçek modelleme sorunlarının soyutta tanımlamak yerine nesnelerle nasıl etkili bir şekilde saldırıya sokulabileceğini gösterir.


13

Dsimcha’nın çoğuna verdiği cevaba katılmıyorum:

  1. OO'yu baştan öğretmek, kendi içinde gerçekten de kötü bir fikir değil, aynı zamanda usul dillerini de öğretmek değildir. Önemli olan, insanlara OO veya prosedürden bağımsız olarak açık, özlü, uyumlu bir kod yazmalarını öğretmemizdir.

  2. İyi OO programlarında münferit yöntemler hiç prosedürel bakma eğiliminde DEĞİLDİR. Bu, OO dillerinin evrimi ile giderek daha da artmaktadır (C # 'yu okudum çünkü C ++ dışında bildiğim tek OO dili) ve gün geçtikçe daha karmaşık hale gelen sözdizimleri (lambdas, LINQ to object, vb.). İşlemsel yöntemlerde OO yöntemleri ve prosedürleri arasındaki tek benzerlik, yakın zamanda her zaman değişeceğinden şüphelendiğim her birinin doğrusal doğasıdır.

  3. Veri yapılarını anlamadan bir yordamsal dile hakim olamazsınız. İşaretçi kavramı, işlemsel diller için olduğu gibi OO dilleri için de önemlidir. Örneğin, prosedür dillerinde oldukça yaygın olan parametreleri referans olarak aktarmak, işaretçileri herhangi bir OO dilini öğrenmek için gerektiği kadar anlamanızı gerektirir.

  4. Tasarım kalıplarının OO programlamasında henüz erken öğretilmesi gerektiğini düşünmüyorum, çünkü bunlar OO programlaması için temel değil. Biri tasarım kalıpları hakkında hiçbir şey bilmeden kesinlikle iyi bir OO programcısı olabilir. Aslında bir kişi, uygun isimlerle belgelendiğini ve kitapların onlar hakkında yazıldığını bile bilmeden, iyi bilinen tasarım kalıplarını bile kullanabilir. Temel olarak öğretilmesi gereken, Tek Sorumluluk, Açık Yakın ve Arayüz Ayrımı gibi tasarım ilkeleridir. Ne yazık ki, bugünlerde kendilerini OO programcıları olarak kabul eden birçok kişi ya bu temel konsepte aşina değiller ya da sadece bunu görmezden gelmeyi seçiyorlar ve bu yüzden dışarıda çok fazla OO kodumuz var.

Orijinal posterin sorusunu cevaplamak için, evet, OO prosedürel programlamaya göre anlamak daha zor bir kavramdır. Çünkü gerçek hayattaki nesnelerin özellikleri ve yöntemleri olarak düşünmüyoruz. Örneğin, insan beyni kolayca “TurnOn” u bir TV yöntemi olarak düşünmüyor, ancak bunu TV'yi insanın çevirdiği bir işlev olarak görüyor. Benzer şekilde, polimorfizm, her gerçek yaşam nesnesini yalnızca bir "yüz" ile gören bir insan beynine yabancı bir kavramdır. Kalıtım yine beynimiz için doğal değildir. Sadece bir geliştirici olduğum için oğlumun olacağı anlamına gelmez. Genel olarak konuşursak, insan beyninin OO öğrenmek için eğitilmiş olması gerekirken, prosedür dilleri daha doğaldır.


2
+1 - Ben de temel olarak OOP öğretimi için tasarım modellerinin gerekli olduğunu düşünmüyorum, iyi bir OOP programcısı olabilir ve herhangi bir tasarım modelini bilemeyebilirsiniz. Kapak tarafında, bilinen tasarım desenlerinin doğal olarak iyi OOP programlayıcılarından çıktığını görme eğilimindesiniz. Tasarım desenleri her zaman keşfedilir, icat edilmez.
Gary Willoughby

1
+1 - Harika cevap. Belirtmiş olduğun dördüncü noktayı beğendim. Gerçekten, tasarım patikalarının gerçekte ne olduğunu bilmeden iyi bir OO programcısı olabileceği
Karthik Sreenivasan

# 4 ile aynı fikirdeyim çünkü çoğu tasarım deseni, dilin sınırlamaları etrafında açıkça kodlama yapmak için bir bubblegum / koli bandı yaklaşımından başka bir şey değildir. Diğer paradigmalarda, tasarım desenleri tamamen farklı olabilir ve kendi sınırlamalarına göre olabilir. 2'ye katılmıyorum, LINQ ve lambdalar hala usule uygun bir şekilde yürütülüyorlar ve özenle paketlenmiş daha yüksek seviyeli soyutlamalar sağlıyorlar. JavaScript gibi dinamik bir şekilde yazılan yordamsal / işlevsel bir dille gelişmek için önemli miktarda zaman harcayın; ne demek istediğimi anlayacaksınız.
Evan Plaice

6

Bence birçok programcı başlangıçta tasarım ve başlangıçta planlama konusunda güçlük çekiyor. Biri sizin için tüm tasarımı yapmış olsa bile, OOP prensiplerinden uzaklaşmak hala mümkündür. Bir sürü spagetti kodu alıp sınıfa attığımda, bu gerçekten OOP mu? OOP'yi anlamayan biri hala Java'da program yapabilir. Ayrıca, belli bir metodolojiye uymaya istekli veya buna katılmamak konusunda anlaşılması zor olanı karıştırmayın.


5

Sen okumalı Nesneleri hiç? Eh, Neredeyse hiç. (ACM üyeliği gereklidir) OOP'un çok zor olduğunu öne süren Mordechai Ben-Ari tarafından, çünkü aslında herhangi bir şeyi modellemek için doğal olan bir paradigma değil. (Her ne kadar makale hakkında endişelerim olsa da, bir programın bir OO dili kullanan bir prosedürel paradigmaya karşılık OOP paradigması üzerine yazıldığını söylemek için bir programın hangi kriterlere uyması gerektiğini düşündüğü açık değildir.)


5

Nesneye Yönelik Programlama kendi içinde zor değildir.

Zor kısmı iyi yapmak geliyor. Kesiği kodun arasına nereye koyacaksınız, böylece işleri ortak temel nesneye kolayca taşıyabilir ve daha sonra genişletebilirsiniz? Kodunuzu, başkaları tarafından kullanılabilir hale getirme (sınıfları genişletme, proxy'leri sarma, geçersiz kılma yöntemi), bunu yapmak için çemberlerin içinden atlamayın.

Bu zor olan kısımdır ve eğer doğru yapılırsa çok şık olabilir ve eğer kötü yapılırsa çok sakar olabilir. Benim kişisel deneyimim, bu kez yeterince yapmak için farklı dilde yapmayı dilediğiniz tüm durumlarda olmanızın çok fazla pratik gerektirmesidir .


“Benim kişisel deneyimim, bu kez yeterince yapmak için farklı dilde yapmayı dilediğiniz tüm durumlarda olmanız için çok fazla pratik gerektiriyor.” OOP, yanlış yapmamak için kodlanmış bir yol listesi gibi gözüküyor, bu şekilde yanlış olana kadar mantıklı değil.
Jared Updike

@Jared, tam değil. Sodukus'u çözmek için karşılaştırın. Çözmek için yapabileceğiniz çeşitli numaralar var, ancak geri izleme olmadan iyi yapmak için zaman ve pratik gerekiyor.

Biri ortak bir ata gibi bir "ortak temel nesne" olduğunu düşünüyorsa, o zaman netleşir. Gerçekten bu kadar basit. B / c'yi anlamak zordur, zeki görünmeye çalışan insanlardan o kadar çok yanıltıcı açıklama vardır.
annoying_squid

4

Richard Feynman'ın, insanların düşünürken kafasında nasıl tamamen farklı metodolojiler yaşayabileceklerini tartışan bir video izliyordum - yani tamamen farklı.

Üst düzey tasarım yaptığımda, nesneleri görselleştiriyorum, onları görebiliyorum, arayüzlerini görebiliyorum ve bilgilerin hangi yollardan geçmesi gerektiğini görebiliyorum.

Ayrıntıları hatırlamakta da güçlük çekiyorum ve OO'yu harika bir organizasyonel yardım aracı olarak buldum - gevşek bir şekilde organize edilmiş bir alt yordamlar listesinde tarama yapmaktan çok daha kolay işlevsellik bulmak.

Benim için OO büyük bir avantajdı, ancak aynı şekilde görselleştiremiyorsanız ya da üst düzey mimari yapmıyorsanız, muhtemelen anlamsız ve sinir bozucu olur.


+1 Aynı şekilde hissediyorum, ama katı karışımın herkes için olmadığını fark etmenizi sağlayan Ruby karışımları da dahil olmak üzere ters yönde çok fazla baskı var.
Dan Rosenstark

@Yar Yep, söylediğim şey buydu. Kişisel olarak daha iyi bir şey hayal edemesem de (ve Ruby kullandığım yıl bana NUTS getirdi), herkesin farklı bir görme biçiminin olduğunu kabul etmeye başladım. Belki bazı insanlar görselleştirmek yerine düşünürken dokunma veya duyma kullanırlar ve OO onlar için tekmeleyemez.
Bill K

Ayrıca, daha doğal adlandırma kurallarını desteklemeye de yardımcı olduğunu düşünüyorum. Artık (gibi işlev adını içine bir fonksiyonun türünü kodlamak gerekir INSTR) - adı tipine bağlı olduğu için (gibi string::find)
Ken Bloom

@Ken hemfikir olmama rağmen, bunun OO'dan daha güçlü bir yazma meselesi olduğunu düşünüyorum - Ruby'nin OO'su var ama ördek yazmasından dolayı çok fazla türde bilgi kaybediyorsunuz. "sihirli" çalışması için hangi büyü yönteminin uygulanması gerektiğini biliyorsunuz.
Bill K

@Bill, haklısın. Genel programlamayı destekleyen bir dil sorunudur. Haskell gibi modül ve typeclass sistemleri ile güzel doğal adlandırma kuralları alabilirsiniz ve Haskell hakkında bir OO yoktur. Eğer C aşırı yüklenmiş olsaydı, C de aynı türden genel isimleri bulabilirdiniz
Ken Bloom

4

OW ile tanışmadan önce GW-Basic ve Turbo Pascal programlamalarını biraz daha bitirdim, bu yüzden başlangıçta başımı dikti .

Başkalarına ne olduğu hakkında hiçbir fikrim yok, ama bana böyle oldu: programlama konusundaki düşünce sürecim tamamen prosedüreldi. Gibi: "böyle ve böyle olur, sonra böyle ve böyle olur", vb. Değişkenleri ve verileri, programın akışında akıcı aktörlerden başka bir şey olarak düşünmedim. Programlama "eylemlerin akışı" idi.

Sanırım kavraması kolay olmayan bir şey (şimdi bana göründüğü kadar aptalca), veri / değişkenlerin gerçekten önemli olduğu fikri, sadece "akış" programındaki akıcı aktör olmaktan daha derin bir anlamda. Ya da bu başka bir deyişle: ne yoluyla anlamaya çalışan tuttu olur doğrusu neyi yoluyla daha olduğunu iyice kavrayarak gerçek anahtarı olan.


İlginç bakış açısı. Muazzam bir C ++ projesini anlama mücadelesi verirken, öncelikle veri girişleri gibi bazı "girdi" lerden bazı "çıktılar" a kadar olan "sinyal yolunu" düşünerek zıt olduğumu düşünüyorum. Ben de çok fazla Basic ve Pascal yaparken, ilk teknik düşüncem elektronikle ilgiliydi.
DarenW

3

Bunu anlamanın zor olduğunu sanmıyorum, ancak sorgulayan programcıların birçoğu işlemsel dillerden gelen kavram için yeni olabilir.

Gördüklerimden / okuduğum kadarıyla (en azından forumlarda) OOP'tan bir 'sonuç' arayın. Eğer geri dönüp kodunu değiştirmeyen bir prosedürel programcıysanız, faydalarını anlamak zor olabilir.

Ayrıca, orada çok fazla kötü OOP var, eğer insanlar okuyor / görüyorsa o zaman neden zor bulduklarını anlamak kolaydır.

IMO 'klikleyene kadar' beklemeniz veya gerçek bilgili biri tarafından öğretilmeniz gerekiyor, acele edemeyeceğinizi düşünüyorum.


5
Akademik bir ortamdan geliyorsanız, orada yazdığınız oyuncak programlarının türleri OOP'da da gerçekten anlamsız görünüyor. Üniversitede C öğrenmeye başladım ve bunu kavramak kolaydı çünkü her program 1 sayfa, 100 satırdan azdı. O zaman OOP'yi öğrenmeye çalışırsınız ve tüm bu bagajı ve nesnelerin üstünü aynı şeyi yapmak için gerektirir ve anlamsız görünüyor. Ancak birçok dosya ve birkaç bin satır arasında bir program yazana kadar, herhangi bir programlama stilinin neden faydalı olduğunu görmek zor.
CodexArcanum

3

Bence OOP'un birçoğu için zor olmasının sebebi, aletlerin onu gerçekten kolaylaştırmadığıdır.

Günümüzde bilgisayar dilleri, bilgisayarda neler olup bittiğinin bir soyutlamasıdır.

OOP soyutlamaları temsil etmek için soyutlanmış bir yoldur.

Bu yüzden bir soyutlama ile soyutlamalar oluşturmak için bir soyutlama kullanıyoruz. Buna, soyutladığımız şeyin genellikle çok karmaşık fiziksel / sosyal etkileşimler olduğunu ve merak etmediğini ekleyin.


2

Aslında, onu öğrenme konusundaki bazı mücadelelerimden doğan "Nesneye Yönelik Programlamada Mücadele" adlı bir blogum var. Anlamak benim için özellikle zordu çünkü prosedürel programlamayı kullanarak çok fazla zaman harcadım ve bir nesnenin nitelikler ve davranışlar topluluğuyla temsil edilebileceği fikri üzerine kafa yormakta zorlandım (alışkınım) basit bir değişkenler ve yöntemler topluluğu).

Ayrıca, bir dili nesne yönelimli yapan bir çok kavram vardır - kalıtım, arayüzler, polimorfizm, kompozisyon vb. yöntemsel programlamada, sadece değişkenler için bellek ayırma ve giriş noktası diğer yöntemlere çağrı gibi şeyleri anlama meselesidir.


Kabul ediyorum - insanların OO ile yaşadıkları zorlukların çoğu, kendilerini 'usule dayalı' düşünmek için eğitmiş olmalarıdır. OO ile ilgili olarak doğal olarak zor bir şey yoktur, ancak usule ilişkin teknikleri 'bilirseniz', bir şeyleri yapılandırmanın başka bir yolunu görmek oldukça şaşırtıcı olacaktır.
Kirk Broadhurst

Hiç şüphe yok ki prosedürel programlamadan tamamen farklı bir düşünce şeklidir. Ancak birçoğunun söylediğinin aksine, A) doğal olmayan bir düşünce tarzı ve B) karmaşık değildir. Sadece iyi öğretilmediğini düşünüyorum.
annoying_squid

2

Motivasyon. Nedenini anlamadığınızda ve ne yaptığınıza bakamadığınızda ve doğru yapıp yapmadığınızı anlayamadığınızda bir şeyi öğrenmek zordur.

Gerekli olan, faydalı şeyler yapmak için OO kullanan küçük projelerdir. Tasarım desenleri üzerine bir kitap incelemenizi ve açıkça yararlı olan ve OO ile iyi çalışan bir tane bulmanızı öneririm. (Denemeyi bir kez denediğimde Strateji kullandım. Flyweight veya Singleton gibi bir şeyler kötü tercihler olurdu, çünkü genel olarak nesneleri kullanma, bir şeyi başarmak için nesneleri kullanma yolları değildi.)


İnsanlar hep Singleton hakkında konuşurlar, ama o her zaman partiye davet edilir. Ama doğru, o OO olmayan DP.
Dan Rosenstark

-1

Bence yaşa (deneyim için bir vekil olarak yaş) ve daha da önemlisi ilgi alanlarına bağlı. Eğer "genç" (yani, belki de yeşil) iseniz ve başka bir yolla hiç düşünmediyseniz, bu oldukça basit görünüyor. Öte yandan, şimdiye kadar gördüğünüz en havalı şey olduğunu düşünüyorsanız - 28 yaşında başıma geldi veya bir şey grok yapmak kolaydır.

Öte yandan, eğer Java öğrencilerimin çoğunun yaptığı gibi “bunu neden öğreniyoruz, bu sadece bir tuhaflık” olduğunu düşünüyorsanız, öğrenmesi neredeyse imkansız. Bu, çoğu teknolojide geçerlidir.


1
Çılgınlık mı? Öğrencileriniz kaç yaşında - bu "heves" in onlardan daha yaşlı olduğundan şüpheleniyorum (ilk yaptığım OO - yaptığımı biliyordum - 1983 / 4'te Simula ve Simula o noktada yeni değildi)
Murph

@Murph Bu 2004-2005 yıllarındaydı ve öğrenciler kesinlikle 45-50 yaşlarındaydı (Iberia'daki profesyonel programcılar).
Dan Rosenstark

Tamam, OO olayının başlangıcını nasıl kaçırdıklarını anlayabiliyorum. Fakat 2004/5 itibariyle, duvardan duvara OO duvarları olan .NET'e çok iyi girdik (-: Gelişmekte olan bir soluk olarak tanımlayabileceğiniz şeyler var, ancak çabucak püskürmeyenler iyi şeylere dönüşmeye meyilli
Murph

1
@Murph dürüst olmak gerekirse, bu adamlar Java'ya dönüştürmeye çalıştıkları ana programcılardı. Aslında eğlenceli ve benzersiz bir deneyimdi (Java Trainer günlerim için normal bir ücret değil). O ise onlar çok şey gelir ve gider, ama besbelli OO bir tuhaflık daha fazladır gördüğünü, ancak, doğru. Ayrı bir not: Bu Birim Testinin bir fad olarak
biteceğini

-1

Hangi paradigmayı (OOP, fonksiyonel vb.) Seçerseniz seçin, bir bilgisayar programı yazmak için programınızın hangi adımları uygulayacağını bilmeniz gerekir.

Bir süreci tanımlamanın doğal yolu, adımlarını yazmaktır, daha büyük işler için görevi daha küçük adımlara bölersiniz. Prosedürel yol budur, bilgisayar bu şekilde çalışır, adım adım kontrol listenizden nasıl geçersiniz.

OOP farklı bir düşünce tarzıdır. Adım adım yapılması gereken görevlerin bir kontrol listesini düşünmek yerine, nesneleri, yeteneklerini ve ilişkilerini düşünürsünüz. Böylece çok sayıda nesne yazacaksınız, küçük yöntemler ve programınız sihirli bir şekilde çalışacaktır. Bunu başarmak için aklınızı bükmeniz gerekir ...

İşte bu yüzden OOP zor. Her şey bir nesne olduğu için, yaptıkları tek şey başka nesnelerden bir şeyler yapmasını istemektir ve diğer nesneler temelde bazılarını yapar. Böylece bir OOP programındaki kontrol, nesneler arasında çılgınca ileri ve geri atlayabilir.


-1

Şu anda programlamayı öğrenen ve bu alanda bazı sorunları olan biri olarak, bu kavramın belirli uygulamalarının olduğu gibi kavramın anlaşılmasının o kadar zor olduğunu sanmıyorum. Bunu söylüyorum çünkü OOP fikrini alıyorum ve onu PHP'de yaklaşık bir yıldır kullanıyorum, fakat C # 'ya geçip diğer programcıların nesneleri kullandıklarına bakarken, birçok insanın böyle yaptığını buldum. sadece anlamadım ki. Bu, özellikle OOP ilkelerini daha iyi anlayabilmem için beni yolun aşağısına çeken şeydi.

Tabii ki, bu sorunun doğal OOP dili konusundaki deneyim eksikliğimden kaynaklandığını ve zaman geçtikçe ne olduğum gibi yeni bir programcı için belirsiz olacak nesneleri kullanmanın yeni yollarını bulacağımı fark ettim. şu anda yaşıyor. Jerry Coffin, özellikle yaptığı açıklamada, birkaç kez buna değiyor:

Bu, özellikle bir yandan OOP'nin büyük bir avantajının gerçeği daha yakından modellediği söylendiğinde sorunlu hale geliyor, ancak LSD'den ilham alan en basit ve en açık kısımlarının bile berbat göründüğü bir şeyi alarak başlıyorsunuz. gerçeklik.

Bunu çok doğru buluyorum, çünkü birileri gerçekten gerçek olmayan şeyler için sınıflar oluştururken gördüğümde sık sık alıyorum - belirli bir örnek benden kaçıyor, ama anında en yakın olanı mesafe gibi davranmak. Bir nesne (bir dahaki sefere bu aynı karışıklığa neden olan bir şey gördüğümde düzenleme yapacağım). OOP bazen geçici olarak kendi kurallarını göz ardı ediyor ve daha az sezgisel hale geliyor. Bu, nesneler, onları içine alan bir sınıftan miras kalan nesneler ürettiğinde, vb. Meydana gelmekten daha sık meydana gelir.

Benim gibi biri için, nesneler kavramının, başka bir şey olmazsa, bir nesne gibi bir şeyi ele almayı içeren birden fazla yüze sahip olduğunu düşünmeye yardımcı olur. Uzaklık gibi bir şey, sadece küçük bir paradigma kayması ile birlikte, teorik bir nesne olarak karşımıza çıkabilir, ancak elinizde tutulacak bir nesne değil. Bunu, bir takım özelliklere sahip olmak, ancak özelliklerine erişmek gibi daha soyut davranışlardan oluşan bir davranış olarak düşünmek zorundayım. Bunun benim anlayışımın anahtarı olduğu konusunda olumlu değilim, ancak mevcut çalışmalarımın öncü olduğu görülüyor.


1
Bir çift nokta veya nesne, bir nesne olarak kabul edilmelidir. Ve mesafe nesneden bir fonksiyon olarak alınmalıdır. Nesneleri kullanmak, her şeyden nesne yaptığınız anlamına gelmez.
Gangnus

Dediğim gibi, mesafe kötü bir örnekti. Her şeyden bir nesne yapmak için, özellikle gerçekleştiğim şeyi, aslında yaptığım şeyi değil - ki bu henüz bir şey değil.
dsimer

Dile bağlıdır - SmallTalk'ta mesafe (ve her şey) bir nesnedir. Fakat C # 'da bunun kötü olacağını söylemiştiniz.
Gangnus

-2

Nesne yönelimli programlama (POOP) prensiplerini öğrenirken terminolojiler yoldaki çarpışmamdı. O zaman parçaların yer almaya başlamasının temellerini anlıyorsunuz. Tıpkı yeni kavramları öğrenen her şey gibi biraz zor.

Tasarım desenlerinin en azından OOP'a paralel olarak ele alınması gerektiği konusunda anlaştılar.


-2

Benim için ana sıçrama sadece OOP'un soyut kavramını anlamaktı. Şimdi genel olarak programlama konusunda çok yeniyim, bir buçuk yıldan beri bir buçuk senedir programlama yapıyorum, bu yüzden OOP'a girişim Actionscript ve Processing ile yapıldı. Actionscript kodlamasını ilk öğrendiğimde, OOP'de değildi. Doğrudan Eylemler paneline kodlamayı öğrendim ve programlamanın temel temellerini (değişkenler, fonksiyonlar, döngüler vb.) Öğrendim. Bu yüzden Flash veya Processing'te doğrudan sahneye bir şey yaptığımı öğrendim.

OOP bir şeylere girdiğinde, kullanıp kullanabilmek için bir nesnede yöntemler ve özellikler yaratabileceğimi fark etmek, ilk başta kavramam biraz zordu. Her şey çok soyut ve işlenmesi zordu ancak programlama dilleri kendilerini çok daha iyi bir hale getirdi ancak bu bağlantıları ilk başta yapmak için bir inanç sıçraması oldu.


vay bunun bir parçası hiç mantıklı gelmedi. "Her şey OOP alınca anlamak çok daha kolay hale sınıflar vb nesnelerin örneklerini Ama programlama dilleri arasında işlemek için çok soyut ve zordu Ama biraz ilk başta bu bağlantıları yapmak için faitl bir sıçrama aldı."

-2

Yemek tarifi

İyi OOP anlayışı = İyi Mentor veya İyi Kitaplar Veya Her ikisi + Kişisel İlgi + Uygulama.

Kişisel ilgi

Benim kişisel tecrübelerime göre kişisel ilgi, ustalardan veya iyi kitaplardan veya her ikisinden de bir araya getirilmiş doğru girdilerle usule dayalı programlamadan OOP'a köprüyü geçmenin uzun bir yoludur .

Uygulama, Uygulama ve Uygulama

OOP'yi daha iyi anlamak için en iyi arkadaşım pratikten başka bir şey değildi . Bu kesinlikle OOP yeteneklerinizi geliştirecektir.

Diyor ki, “Zor işin yerini tutamaz, başarının kısayolu olmaz”.

İyi şanslar!

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.