Fonksiyonel programlama ve Nesneye Yönelik programlama [kapalı]


784

Şimdiye kadar esas olarak OO programlamasına maruz kaldım ve fonksiyonel bir dil öğrenmek için sabırsızlanıyorum. Sorularım:

  • Nesneye yönelik işlevsel programlamayı ne zaman seçersiniz?
  • Fonksiyonel programlamanın daha iyi bir seçim olduğu tipik problem tanımları nelerdir?



1
benzer soru cs.se de fonksiyonel programlamanın zorunlu stile göre daha iyi sonuçlar verdiği örnek nedir kapattı . geleneksel bilgelik, birinin diğerinden üstün olmadığı veya basit ölçütlerle karşılaştırılamaz olduğu veya farklı amaçlarla kullanıldığı gibi görünmektedir ... fonksiyonel programlama daha bilimsel / akademik kökenlere ve kullanımlara sahiptir ve endüstride daha az yaygındır bu yüzden soru aynı zamanda bir "sanayi ve akademi" çözülemez pov / çatışma oluşturur. fonksiyonel programlamada OOP
sytle

" OO hareketli parçaları kapsülleyerek kodu anlaşılabilir kılar. FP hareketli parçaları en aza indirerek kodu anlaşılabilir kılar. " --Micheal Feathers, 2010
jaco0646

Yanıtlar:


1193

Nesneye yönelik işlevsel programlamayı ne zaman seçersiniz?

Farklı türde bir yazılım gelişimi öngördüğünüzde:

  • Nesneye yönelik diller, şeyler üzerinde sabit bir işlem kümeniz olduğunda iyidir ve kodunuz geliştikçe, öncelikle yeni şeyler eklersiniz. Bu, mevcut yöntemleri uygulayan yeni sınıflar eklenerek gerçekleştirilebilir ve mevcut sınıflar tek başına bırakılır.

  • İşlevsel diller, sabit bir şeyler kümeniz olduğunda iyidir ve kodunuz geliştikçe, öncelikle mevcut şeylere yeni işlemler eklersiniz . Bu, mevcut veri türleriyle hesaplanan yeni işlevler eklenerek gerçekleştirilebilir ve mevcut işlevler tek başına bırakılır.

Evrim yanlış yola girdiğinde sorunlarınız olur:

  • Nesneye yönelik bir programa yeni bir işlem eklemek, yeni bir yöntem eklemek için birçok sınıf tanımının düzenlenmesini gerektirebilir.

  • İşlevsel bir programa yeni bir tür şey eklemek, yeni bir vaka eklemek için birçok işlev tanımının düzenlenmesini gerektirebilir.

Bu sorun yıllardır iyi bilinmektedir; 1998'de Phil Wadler ona "ifade sorunu" adını verdi . Bazı araştırmacılar, ifade sorununun mixins gibi dil özellikleriyle ele alınabileceğini düşünmesine rağmen, geniş çapta kabul gören bir çözüm henüz ana akımdan etkilenmedi.

Fonksiyonel programlamanın daha iyi bir seçim olduğu tipik problem tanımları nelerdir?

Fonksiyonel diller, sembolik verilerin ağaç formunda manipüle edilmesinde mükemmeldir. Favori bir örnek, kaynak ve ara dillerin nadiren değiştiği derleyicilerdir (çoğunlukla aynı şeyler ), ancak derleyici yazarları her zaman yeni çeviriler ve kod geliştirmeleri veya optimizasyonları ekler (şeyler üzerinde yeni işlemler). Derleme ve çeviri daha genel olarak işlevsel diller için "katil uygulamalar" dır.


119
Bu cevabın arkasında ciddi zen var. Bazı OOP tasarım modellerinin (Ziyaretçi) aslında yeni işlemler ekleme sorununun üstesinden gelmeye çalışan hackler olduğu gerçeğini aydınlatıyor.
Jacobs Data Solutions

54
JavaScript'te her şeye sahip olabilirsiniz.
Erik Reppen

61
@ErikRep sorusunun hangi noktada ortaya çıktığını, fonksiyonel özellikleri ne zaman kullanmayı ve nesne yönelimli özellikleri ne zaman kullanmayı seçersiniz?
Norman Ramsey

7
@NormanRamsey JS'de karıştırmak nadir değildir ve birinci sınıf işlevler JS OOP ile ilgili birçok özelliğe bağlıdır. JS'nin dizi sıralaması, bazı güçlü veri yapıları üretebilen işlevleri bir arg olarak alır. Çoğu yöntem sadece referans olduğu için jquery nesnelerini çok hafif bellek-konuşmada tutmak için kapaklar + geçirilen bir işlev kullanılır. Vb ...
Erik Reppen

9
@NormanRamsey: SICP çizgileri boyunca çok iyi bir cevap. Bu sınıflandırmaya göre, fonksiyonel ve prosedürel programlama nesne yönelimli programlamanın karşı tarafında birlikte gruplandırılır. Bu, 1980'lerin sonunda 1990'ların sonlarında OOP patlamasını açıklayabilir: GUI'ler ana akım haline geldiğinde, OOP bunları modellemek için iyi bir yaklaşım olduğunu kanıtladı çünkü normalde sabit bir dizi işleminiz var (boya, açık, kapalı, yeniden boyutlandırma) ve gittikçe artan sayıda widget. Tabii ki, bu, OOP'nin herhangi bir uygulama için prosedürden daha iyi olduğu anlamına gelmez, örneğin.
Giorgio

177

İki paradigma arasında seçim yapmak zorunda değilsiniz. Birçok işlevsel kavram kullanarak OO mimarisi ile yazılım yazabilirsiniz. FP ve OOP doğada diktir .

Örneğin C # örneğini ele alalım. Çoğunlukla OOP diyebilirsiniz, ancak birçok FP kavramı ve yapısı vardır. Linq'i düşünürseniz , Linq'in var olmasına izin veren en önemli yapılar doğada işlevseldir: lambda ifadeleri .

Başka bir örnek, F #. Çoğunlukla FP olduğunu söyleyebilirsiniz, ancak birçok OOP kavramı ve yapısı vardır. Sınıfları, soyut sınıfları, arayüzleri tanımlayabilir, kalıtımla başa çıkabilirsiniz. Değiştirilebilirliği, kodunuzu daha net hale getirdiğinde veya performansı önemli ölçüde artırdığında da kullanabilirsiniz.

Birçok modern dil çok paradigmadır.

Önerilen okumalar

Aynı teknede olduğum için (OOP arka planı, FP öğrenimi), size gerçekten takdir ettiğim bazı okumalar öneririm:


8
@duffymo: Yorumunuz, sizin ifade ettiğiniz şekilde, çoğunlukla anlamsız. Kimse dilleri, sanal makineleri veya platformları karşılaştırmak istemiyor, teşekkürler.
Bruno Reis

6
@Bruno - ".NET'in gücü" ne yanıt. Rahatlayın.
duffymo

6
Komik, anlamsız yorumu hakkında Dykam'ı sakladığını görmüyorum. Ben bakmıyorken moderatör olarak mı aday gösterildiniz? Burada senden başka kimse alev almıyor. Tekrar söyleyeceğim - rahatla.
duffymo

4
Heh, biraz alev almaya başlarsam özür dilerim. Diğer platformların daha az güçlü olduğunu söylemek istemedim, sadece .NET sadece OOP'yi desteklemiyor. Örneğin kuyruk çağrı optimizasyonu vardır.
Dykam

5
@nawfal, iki paradigmada bazı içsel özelliklere işaret edip uyumsuz olduklarını söyleyene kadar, diktirler: tartışmanın kalbi budur. FP, tanım gereği zorunlu programlama ile uyumlu değildir, ancak OOP zorunlu programlama ile sınırlı değildir. Bu kavramlar için farklı kelimelere sahip olmamızın nedeni, onlarla ilgili konuşabilmemizdir: onları bir araya getirdiğinizde, bizi gereksiz yere yeni kelimeler bulmaya zorlarsınız.
DavidS

31

Nesneye Yönelik Programlama şunları sunar:

  1. Kapsülleme,
    • iç durumun kontrol mutasyonu
    • iç temsile bağlantıyı sınırlama
  2. Alt tipleme, izin verme:
    • uyumlu tiplerin ikamesi (polimorfizm)
    • uygulamayı sınıflar arasında paylaşmanın kaba bir yolu (uygulama mirası)

Haskell'de ve hatta Scala'da Fonksiyonel Programlama, tip sınıflarının daha genel mekanizması aracılığıyla değiştirmeye izin verebilir. Değişken iç durum ya cesaret kırılmış ya da yasaklanmıştır. İç temsilin kapsüllenmesi de sağlanabilir. İyi bir karşılaştırma için Haskell vs OOP'ye bakınız .

Norman'ın "İşlevsel bir programa yeni bir şey eklemek, yeni bir vaka eklemek için birçok işlev tanımını düzenlemeyi gerektirebileceğini" iddia ediyor. fonksiyonel kodun tip sınıflarını ne kadar iyi kullandığına bağlıdır. Belirli bir Özet Veri Türü üzerinde Desen Eşleştirme bir kod tabanına yayılmışsa, gerçekten de bu sorundan muzdarip olursunuz, ancak belki de başlamak kötü bir tasarımdır.

DÜZENLENMİŞ Tür sınıfları tartışılırken örtük dönüşümlere yapılan referans kaldırıldı. Scala'da tip sınıfları, dönüşümlerle değil, örtük parametrelerle kodlanır, ancak örtülü dönüşümler, uyumlu türlerin ikame edilmesinin başka bir yoludur.


3
Tipik sınıflar, diğer türlere örtük dönüştürme mekanizması değildir. Bir tür polimorfizm sağlamak için bir tür için tanımlanan bir dizi fonksiyonun açıklamasıdır. Java tarzı OOP'tan en yakın şey arayüzler olurdu, ancak Haskell tiplerinin bazı önemli farklılıkları var.
Zak

25
  1. Çok eşzamanlı bir ortamdaysanız, saf fonksiyonel programlama yararlıdır. Değişken durumun olmaması eşzamanlılığı neredeyse önemsiz hale getirir. Bkz. Erlang.

  2. Çok değişkenli bir dilde, değişebilir durumun varlığı bir uygulama detayı olmalı ve dolayısıyla FP sorun alanı için iyi bir modelse bazı şeyleri işlevsel olarak modellemek isteyebilirsiniz. Örneğin , D programlama dilinde Python veya std.range içindeki liste kavrayışlarına bakın . Bunlar fonksiyonel programlamadan esinlenmiştir.

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.