OOP ve Fonksiyonel Programlama - Prosedürel [kapalı]


237

Bu programlama paradigmaları arasındaki farklar nelerdir ve belirli sorunlara daha uygun mu veya herhangi bir kullanım örneği diğerinden daha iyi mi?

Mimari örnekler takdir!


Bu tam bir cevap değil, ama ben burada "fonksiyonel" "OO" tarzı (F # bağlamında) nasıl etkiler / kontrast hakkında biraz yazıyorum: lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!511. giriş
Brian

Bunu okumayı düşünebilirsiniz ! Ne zaman kullanılacağına birçok örnek vardır ki ne karınca temel farklar, artı / eksi vs
Nikita İgnatov



Bob Amca bunu tweetledi . Ve burada da .
jaco0646

Yanıtlar:


129

Hepsi kendi yollarında iyidir - Aynı sorunlara basitçe farklı yaklaşımlardır.

Tamamen prosedürel bir tarzda, veriler üzerinde çalışan fonksiyonlardan yüksek oranda ayrılma eğilimindedir.

Nesneye yönelik bir tarzda, veriler beraberinde bir işlev koleksiyonu taşıma eğilimindedir.

İşlevsel bir tarzda, veri ve işlevler, işlevlerin gerçekte nasıl kullanıldığı konusunda daha fazla esneklik sunarken (Lisp ve Şema'da olduğu gibi) birbirleriyle daha fazla ortak yönlere sahip olma eğilimindedir. Algoritmalar ayrıca döngüler ve yineleme yerine özyineleme ve kompozisyon açısından tanımlanma eğilimindedir.

Tabii ki, dilin kendisi sadece hangi stilin tercih edildiğini etkiler. Haskell gibi saf işlevsel bir dilde bile, prosedürel bir tarzda yazabilirsiniz (bu çok cesaret kırılmış olsa da) ve C gibi bir prosedürel dilde bile, nesne odaklı bir tarzda (GTK + ve EFL API'ları).

Açıkçası, her paradigmanın "avantajı" sadece algoritmalarınızın ve veri yapılarınızın modellenmesidir. Örneğin, algoritmanız listeler ve ağaçlar içeriyorsa, işlevsel bir algoritma en mantıklı olabilir. Veya, örneğin, verileriniz oldukça yapılandırılmışsa, dilinizin yerel paradigmasıysa, bunları nesne olarak oluşturmak daha mantıklı olabilir - veya, monad'ların işlevsel bir soyutlaması kadar kolay bir şekilde yazılabilir; Haskell veya ML gibi yerel diller paradigmasıdır.

Hangi seçeneği kullanacağınız, projeniz ve dilinizin desteklediği soyutlamalar için daha anlamlı olan şeydir.


5
Söyledikleriniz, yazdıklarınızı yansıtmıyor gibi görünüyor. "Artıları ve eksileri" olmadığını ve sonra nasıl farklı yaklaşımlar olduğunu söylüyorsunuz. Neden birisi herhangi bir duruma göre bir yaklaşımı diğerine tercih eder ki? güçlü ve zayıf yönleri, artıları ve eksileri, ne derseniz deyin, varlar! Birinin doğası gereği daha iyi olduğunu söylemiyorum, siz de yapmadınız. Gerçekten söylemeye çalıştığın şey olduğuna inanıyorum. seçilen herhangi bir yaklaşımın başka bir yaklaşıma göre olumlu ve olumsuz olmadığına gerçekten inanmıyorsanız.
JM Becker

1
@TechZilla: İfademin zayıf olduğuna katılıyorum, ama demek istediğim, işaret edebileceğiniz ve X dilinin Y algoritmasından U ve dil yazmak için daha uygun olduğunu kabul etmeden X dilinin Y'den daha iyi olduğunu söyleyebileceğiniz özelliklerin bir listesi olmadığıdır. Her ikisi de her iki dilde de kolayca uygulanabilirken, Y algoritması V yazmak için daha uygun olabilir.
greyfade

2
Prosedürel ve fonksiyonel arasındaki fark benim için net değil. College'da Scheme / Rackett öğreniyorum, ancak gerçekten C veya PHP ile prosedür arasındaki büyük farkı göremiyorum, biraz örnek verebilir misiniz?
Leonel

7
@Leonel: Çoğu insanın değineceği en büyük fark, prosedürel dillerde bir for döngüsü kullanabilirsiniz, ancak işlevsel diller, böyle bir şey yoktur - bunun yerine, aynı görevi gerçekleştirmek için işlevlere özyinelemeli çağrılar kullanırsınız. İşlevsel diller aynı zamanda işlevleri birinci sınıf nesneler yaparlar - sayı gibi istediğiniz gibi iletebilirsiniz - ancak bunu C'de yapamazsınız (ve PHP'nin desteği bozulur).
greyfade

2
@tastro: Bir paradigma diğerinden daha mantıklı olduğunda. Gerçekten hepsi bu. Bazen kodunuzu işlevlerin bileşimi olarak modellemek daha mantıklı olabilir ve bazen verilerinizi nesne olarak modellemek daha mantıklı olur. Algoritmaları ve veri yapılarını ifade etmenin birçok yolu vardır. OOP ve fonksiyonel olanlar bunlardan ikisidir.
greyfade

25

Mevcut kütüphanelerin, araçların, örneklerin ve toplulukların bu günlerde paradigmayı tamamen ortadan kaldırdığını düşünüyorum. Örneğin, ML (ya da her neyse) nihai çok amaçlı programlama dili olabilir ancak yaptığınız şey için iyi bir kitaplık alamazsanız berbatsınız.

Örneğin, bir video oyunu yapıyorsanız, C ++ 'da daha iyi kod örnekleri ve SDK'lar vardır, bu yüzden muhtemelen daha iyi durumda olursunuz. Küçük bir web uygulaması için, çok hızlı bir şekilde çalışmanızı sağlayacak bazı Python, PHP ve Ruby çerçeveleri vardır. Java, derleme zamanı denetimi ve kurumsal kitaplıklar ve platformlar nedeniyle daha büyük projeler için mükemmel bir seçimdir.

Eskiden farklı diller için standart kütüphanelerin oldukça küçük ve kolayca çoğaltılabildiği durum buydu - C, C ++, Assembler, ML, LISP, vb. ağ iletişimi, şifreleme, grafik, veri dosyası formatları (XML dahil) gibi, dengeli ağaçlar ve karma tablolar gibi temel veri yapıları bile dışarıda bırakıldı!

Python, PHP, Ruby ve Java gibi modern diller artık çok daha iyi bir standart kütüphane ile geliyor ve kolayca kullanabileceğiniz birçok iyi üçüncü parti kütüphaneye sahip, büyük ölçüde kütüphanelerin birbirleriyle çarpışmasını önlemek için ad alanlarını benimsemeleri sayesinde, ve kütüphanelerin bellek yönetim şemalarını standartlaştırmak için çöp toplama.


5
Python, ruby, ... tek uygulama dilleri olduklarından C veya LISP gibi "standart" kütüphanelere sahip değiller. Guido'nun söylediği şey Python, standart yok. Günümüzde herhangi bir özel C veya LISP (ya da her neyse) uygulama, standart olanların ötesinde geniş bir kütüphane seti ile birlikte gelir.
Dan Andreatta

8
Soru, nesne yönelimli, fonksiyonel ve prosedürel programlama arasındaki farklarla ilgiliydi. Bu cevaplarda bahsedilen diller kesinlikle bu yaklaşımlardan birine borç vermiş olsa da, cevap bu kavramların hiçbirinden bahsetmemektedir ... "mevcut kütüphaneler [...] [koz] paradigma" olsun ya da olmasın, eldeki soruya cevap vermiyor, bu yüzden tamamen geçerli bir soruya yöneliyor.
rinogo


20

Bu paradigmaların birbirini dışlaması gerekmez. Python'a bakarsanız, işlevleri ve sınıfları destekler, ancak aynı zamanda işlevler de dahil olmak üzere her şey bir nesnedir. İşlevsel / oop / yordamsal stili tek bir kodda karıştırabilir ve eşleştirebilirsiniz.

Demek istediğim, fonksiyonel dillerde (en azından Haskell'de, çalıştığım tek kişi) herhangi bir ifade yok! işlevleri sadece bir ifade içinde izin verilir !! AMA, fonksiyonlar birinci sınıf vatandaşlar, onları bir dizi başka yetenekle birlikte parametre olarak iletebilirsiniz. Birkaç kod satırı ile güçlü şeyler yapabilirler.

C gibi yordamsal bir dilde iken, işlevleri çevirebilmenin tek yolu işlev işaretçileri kullanmaktır ve bu tek başına pek çok güçlü görevi etkinleştirmez.

Python'da bir işlev birinci sınıf bir vatandaştır, ancak keyfi sayıda ifade içerebilir. Böylece, işlem kodu içeren bir işleve sahip olabilirsiniz, ancak bunu işlevsel diller gibi geçirebilirsiniz.

Aynı şey OOP için de geçerli. Java gibi bir dil, sınıf dışında prosedürler / işlevler yazmanıza izin vermez. Bir işlevi geçirmenin tek yolu, işlevi o işlevi uygulayan bir nesneye sarmak ve sonra o nesneyi etrafa aktarmaktır.

Python'da bu kısıtlamaya sahip değilsiniz.


"Bu paradigmalar birbirini dışlamak zorunda değilsiniz" demek istediğinizi düşünüyorum. 3 tanesi vardır (dil izin verirse) o ideal tek bir programda 3 tanesi birini 2 kullanın veya olabilir de dik.
Joe Pineda

Evet, karşılıklı olarak ayrıcalıklı olmak bunun için daha iyi bir terim! thanks
hasen

14

GUI için Nesneye Dayalı Paradigmanın çok uygun olduğunu söyleyebilirim. Pencere bir Nesnedir, Metin Kutuları Nesnelerdir ve Tamam-Düğmesi de birdir. Öte yandan, String Processing gibi El işleri çok daha az genel masrafla yapılabilir ve bu nedenle basit prosedür paradigması ile daha basittir.

Bunun bir dil sorunu olduğunu da sanmıyorum. Bazılarında ek çaba olsa da, hemen hemen her popüler dilde işlevsel, prosedürel veya nesne yönelimli yazabilirsiniz.


17
"Object = GUI widget" yanlış algılanan için aşağı oy için cazip, ama kaçıracağım. OOP, "Pencere" ve "Düğme" gibi görünür arabirim öğeleri için olduğu gibi, "UserAccount" veya "PendingSale" gibi soyut kavramları temsil etmek için de işe yarar.
Dave Sherohman

5
Bir pencerenin bir nesne olabileceğini yazdım. Her Nesnenin oradan bir pencere olduğu sonucunu nasıl çizersiniz? Bu sadece bir örnekti. Elbette OOP, soyut varlıkları ve ilişkilerini modellemek için de kullanılabilir. Her neyse, aşağı oy kullanmadığınız için teşekkürler. Zaten çok
puanım yok

6
-1. OOP'nin GUI'lerle hiçbir ilgisi yoktur. İdeal olarak, guis tasarlamak için en iyi yöntem harici bir metin dosyası (örn. HTML) kullanmaktır. Dizge işleme gibi şeyler aslında nesnelerle daha iyi yapılır. (C dizeleri hakkında düşünmek) !!
hasen

1
Bilmiyorum, belki sadece bunu gerçekleştirmek için nesnelerle programlama yapmaya alışkınım. Ancak, TextBox Y değeri nesneler kullanılmadan değiştirildiğinde, TextBox X'daki değeri değiştirmek gibi bazı etkileşimli şeyleri nasıl yapardınız? Tamam, sadece her şey için küresel vars kullanabilirsiniz ...
panschk

1
Dize işleme perl'de (Java, C ++ veya C # 100x daha iyi) mükemmel bir şekilde yapılır, ancak dilin dize işlevselliği kesinlikle nesne yönelimli DEĞİLDİR. C'nin dize kullanımı korkunçtu, ancak o zaman C tek prosedürel dil (ne de en iyisi) değildi.
Joe Pineda

6

Sorunuzu cevaplamak için iki öğeye ihtiyacımız var:

  1. Farklı mimari üslup / örüntülerin özelliklerinin kavranması.
  2. Farklı programlama paradigmalarının özelliklerini anlama.

Yazılım mimarisi yazılarında yazılım mimarisi stillerinin / deseninin bir listesi gösterilirWikipeida'daki . Web üzerinde kolayca araştırma yapabilirsiniz.

Kısacası ve genel olarak, Prosedür prosedürü takip eden bir model için iyidir, OOP tasarım için iyidir ve Fonksiyonel yüksek seviye programlama için iyidir.

Bence her paradigmada tarihi okumaya çalışmalı ve insanların neden onu yarattığını görmelisiniz ve bunları kolayca anlayabilirsiniz.

Her ikisini de anladıktan sonra, mimari stil / desen öğelerini programlama paradigmalarına bağlayabilirsiniz.


2

Bence genellikle "karşı" değiller, ama onları birleştirebilirsiniz. Ben de çoğu zaman bahsettiğiniz kelimelerin sadece terim olduğunu düşünüyorum. "Nesne yönelimli" nin ne anlama geldiğini gerçekten bilen az insan vardır, bunlar en şiddetli evanjelistler olsalar bile.


1

Arkadaşlarımdan biri NVIDIA CUDA kullanarak bir grafik uygulaması yazıyor . Uygulama OOP paradigmasına çok iyi uyuyor ve sorun modüllere düzgün bir şekilde ayrılabiliyor. Bununla birlikte, CUDA'yı kullanmak için mirası desteklemeyen C'yi kullanmanız gerekir . Bu nedenle, zeki olmanız gerekir.

a) Belli bir dereceye kadar mirası taklit edecek akıllı bir sistem tasarlarsınız. Yapılabilir!

i) Bir kanca sistemi kullanabilirsiniz Ebeveyn P'nin her bir alt çocuğunun F fonksiyonu için belirli bir geçersiz kılma yapmasını bekleyen .

ii) Yapısal bellek hizalamasını kullanabilirsiniz Çocukları ebeveynlere aktarmak için özelliğini kullanabilirsiniz.

Bu düzgün olabilir, ancak geleceğe yönelik, güvenilir bir çözüm bulmak kolay değildir. Sistemi tasarlamak için çok zaman harcayacaksınız ve projenin yarısında sorun yaşamayacağınızın garantisi yok. Birden fazla mirasın uygulanması , daha da zor olmadığını neredeyse imkansız değildir.

b) Bir program oluşturmak için tutarlı adlandırma politikası kullanabilir ve böl ve fethet yaklaşımını kullanabilirsiniz. Herhangi bir mirasa sahip olmayacaktır, ancak işlevleriniz küçük, anlaşılması kolay ve sürekli biçimlendirilmiş olduğundan buna ihtiyacınız yoktur. Yazmanız gereken kod miktarı artar, odaklanmak ve kolay çözümlere (kesmek) yenmek çok zordur. Ancak, bu ninja kodlama yöntemi C kodlama yöntemidir. Düşük seviye özgürlük ve iyi kod yazma arasında dengede kalmak. Bunu başarmanın iyi bir yolu fonksiyonel bir dil kullanarak prototip yazmaktır. Örneğin, Haskell prototip algoritmaları için son derece iyidir.

Yaklaşım eğilimindeyim b. A yaklaşımını kullanarak olası bir çözüm yazdım ve dürüst olacağım, bu kodu kullanarak çok doğal olmayan hissettim.


İlk c ++ copmpiler C kodu üreten ön işlemcilerden başka bir şey değildi. Bu nedenle, c ++ 'nın TÜM özellikleri - çoklu kalıtım da dahil olmak üzere C kullanılarak uygulanabilir. (C'de c ++ istisna işlemeyi taklit etmek istisnalar için bir tür platform desteği gerektirir, ancak c ++ uygulamaları da bunu gerektirir, bu yüzden temel fikir geçersiz).
Chris Becke

2
@Chris Becke Cevabınız çok felsefi. Birincisi, C'nin (yıllar boyunca) birden fazla standardı vardır, bunlardan hiçbiri c ++ 'ı yalnız C derleyicileri tarafından tamamen benimsenmiştir. C ++ 'ın C sözdizimi kullandığı için C'nin bir üst kümesi olduğunu söylemek çok fazla bir şey ifade etmez çünkü önemli bir çaba harcamadan başka bir C derleyicisinde derlenen bir C derleyicisi için kod bile yazamazsınız. Ayrıca, diğer dillerde sunulan, yeni bir dil tasarlamak için C'yi kullanmadan C'de uygulanması imkansız olan dil özellikleri (tip sistemleri, OOD desteği) vardır (tam da bu yüzden 'yeni diller' vardır)
Sprague

Bilirsin. Yorumumun bu gönderiyle ne kadar alakalı olduğunu daha fazla göremiyorum. : P
Chris Becke

Cuda bir süredir C ++ 'ı destekliyor.
Aryeh Leib Taurog
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.