İşlevsel programlama GoF tasarım modellerinin yerini alıyor mu?


1047

Geçen yıl F # ve OCaml öğrenmeye başladığımdan beri , tasarım modellerinin (özellikle Java'da) zorunlu dillerdeki eksik özellikler için geçici çözümler olduğu konusunda çok sayıda makale okudum. Bulduğum bir makale oldukça güçlü bir iddiada bulunuyor :

Tanıştığım insanların çoğu Çete Dörtlü'nün (GoF) Tasarım Desenleri kitabını okudu . Kendine saygılı herhangi bir programcı, hangi dili kullandığınıza bakılmaksızın kitabın dile agnostik olduğunu ve kalıpların genel olarak yazılım mühendisliği için geçerli olduğunu söyleyecektir. Bu asil bir iddia. Ne yazık ki gerçeklerden çok uzak.

İşlevsel diller son derece etkileyici. İşlevsel bir dilde tasarım desenlerine ihtiyaç yoktur, çünkü dil muhtemelen çok yüksek seviyededir, tasarım desenlerini hep birlikte ortadan kaldıran kavramlarda programlama yaparsınız.

Fonksiyonel programlamanın (FP) temel özellikleri arasında birinci sınıf değerler, körelme, değişmez değerler vb. Gibi fonksiyonlar bulunmaktadır. OO tasarım modellerinin bu özelliklerin herhangi birine yaklaştığı açık değildir.

Ayrıca, OOP'yi destekleyen işlevsel dillerde (F # ve OCaml gibi), bu dilleri kullanan programcıların diğer tüm OOP dillerinde bulunan tasarım desenlerini kullanacağı açıktır. Aslında, şu anda her gün F # ve OCaml kullanıyorum ve bu dillerde kullandığım kalıplarla Java'da yazarken kullandığım kalıplar arasında çarpıcı bir fark yok.

İşlevsel programlamanın OOP tasarım modellerine olan ihtiyacı ortadan kaldırdığı iddiasına dair herhangi bir gerçek var mı? Öyleyse, tipik bir OOP tasarım modeli ve işlevsel eşdeğeri örneğini yayınlayabilir veya ona bağlanabilir misiniz?


18
Steve Yegge'in makalesine bakabilirsiniz ( steve-yegge.blogspot.com/2006/03/… )
Ralph

27
"kitap dil ​​bilimi içermez ve kalıplar genel olarak yazılım mühendisliği için geçerlidir" - bazı dillerin tasarım kalıpları gibi belirli şeyleri ifade etmeleri gerekmediği için kitabın bu iddiayla aynı fikirde olmadığına dikkat edilmelidir: "Kalıplarımız Smalltalk / C ++ düzeyinde dil özelliklerini varsayalım ve bu seçim neyin kolayca uygulanabileceğini ve nelerin uygulanamayacağını belirler [...] CLOS, örneğin Ziyaretçi gibi bir desene olan ihtiyacı azaltan çoklu yöntemlere sahiptir. " (sayfa 4)
Guildenstern

6
Ayrıca, birçok tasarım modelinin yeterince yüksek düzeyde zorunlu dillerde bile gerekli olmadığını unutmayın.
R. Barzell

3
@ R.Barzell Bu “yeterince yüksek düzeyde zorunlu diller” nelerdir? Teşekkürler.
cibercitizen1

5
@ cibercitizen1 yüksek dereceli fonksiyonlar ve anonim fonksiyonlar için destek ile ördek tipi diller Bu özellikler, birçok tasarım deseninin sağladığı gücün çoğunu sağlar.
R. Barzell

Yanıtlar:


1077

Alıntıladığınız blog yazısı iddiasını biraz abartıyor. FP, tasarım desenlerine olan ihtiyacı ortadan kaldırmaz . "Tasarım modelleri" terimi FP dillerinde aynı şeyi tanımlamak için yaygın olarak kullanılmamaktadır. Ama varlar. İşlevsel diller, "sorun X ile karşılaştığınızda, Y'ye benzeyen bir kod kullanın" şeklindeki en iyi uygulama kurallarına sahiptir, bu da temel olarak bir tasarım modelidir.

Bununla birlikte, OOP'ye özgü tasarım modellerinin çoğunun işlevsel dillerde neredeyse alakasız olduğu doğrudur.

Ben o tasarım desenleri söylemek özellikle tartışmalı olması gerektiğini sanmıyorum genelde sadece dilde eksiklikleri yama bulunmaktadır. Ve eğer başka bir dil aynı sorunu önemsiz bir şekilde çözebiliyorsa, diğer dilin bunun için bir tasarım modeline ihtiyacı olmayacaktır. Bu dilin kullanıcıları sorunun var olduğunun farkında bile olmayabilir , çünkü bu dilde bir sorun değil.

Dörtlü Çetenin bu konuda söyledikleri:

Programlama dilinin seçimi önemlidir, çünkü kişinin bakış açısını etkiler. Kalıplarımız Smalltalk / C ++ düzeyinde dil özelliklerini varsayar ve bu seçim neyin kolayca uygulanıp neyin uygulanamayacağını belirler. Prosedür dillerini kabul edersek, "Miras", "Kapsülleme" ve "Çok Biçimlilik" adlı tasarım modellerini dahil etmiş olabiliriz. Benzer şekilde, bazı modellerimiz doğrudan daha az yaygın olan nesne yönelimli diller tarafından desteklenmektedir. CLOS, örneğin Ziyaretçi gibi bir desene olan ihtiyacı azaltan çoklu yöntemlere sahiptir. Aslında, Smalltalk ve C ++ arasında, bazı kalıpların bir dilde diğerinden daha kolay ifade edilebileceği anlamına gelen yeterli farklılıklar vardır. (Örneğin, yineleyiciye bakın.)

(Yukarıdaki, Tasarım Desenlerine Giriş kitabından bir alıntıdır, sayfa 4, paragraf 3)

Fonksiyonel programlamanın temel özellikleri arasında birinci sınıf değerler, körelme, değişmez değerler vb. Gibi fonksiyonlar bulunmaktadır. OO tasarım modellerinin bu özelliklerden herhangi birine yaklaştığı açık değildir.

Birinci sınıf işlevlerin bir yaklaşımı değilse, komut düzeni nedir? :) Bir FP dilinde, bir işlevi başka bir işleve argüman olarak iletmeniz yeterlidir. Bir OOP dilinde, işlevi bir sınıfta tamamlamanız ve bu nesneyi başlatabilir ve daha sonra bu nesneyi diğer işleve geçirmeniz gerekir. Etki aynıdır, ancak OOP'de tasarım deseni olarak adlandırılır ve çok daha fazla kod alır. Ve eğer curried değilse, soyut fabrika deseni nedir? Sonunda aradığınızda ne tür bir değer verdiğini yapılandırmak için parametreleri bir kerede bir işleve geçirin.

Bu nedenle evet, birkaç GoF tasarım deseni FP dillerinde gereksiz hale getirildi, çünkü daha güçlü ve kullanımı daha kolay alternatifler mevcut.

Ama tabii hala vardır desenleri orada tasarım edilir değil FP dillere tarafından çözüldü. Singleton'un FP eşdeğeri nedir? (Singletonların genellikle korkunç bir model olduğunu bir an için dikkate almayın.)

Ve her iki şekilde de çalışır. Dediğim gibi, FP'nin de tasarım desenleri var; insanlar genellikle onları böyle düşünmezler.

Ama monadlarla karşılaşmış olabilirsiniz. "Küresel devletle uğraşmak" için bir tasarım modeli olmasalar da ne bunlar? Bu, OOP dillerinde o kadar basit bir sorun ki orada eşdeğer bir tasarım deseni yok.

"Statik bir değişkeni artırmak" veya "bu soketten okumak" için bir tasarım modeline ihtiyacımız yok, çünkü bu sadece yaptığınız şey .

Bir monadın bir tasarım deseni olduğunu söylemek, Tamsayıların her zamanki işlemleri ve sıfır elementi ile bir tasarım deseni olduğunu söylemek saçmadır. Hayır, bir monad tasarım deseni değil, matematiksel bir modeldir.

(Saf) işlevsel dilde, "tasarım deseni" monadıyla veya aynı şeye izin vermek için diğer yöntemlerden herhangi biri ile çalışmadıkça, yan etkiler ve değişebilir durum mümkün değildir.

Ayrıca, OOP'yi destekleyen işlevsel dillerde (F # ve OCaml gibi), bu dilleri kullanan programcıların diğer tüm OOP dillerinde bulunan tasarım desenlerini kullanacağı açıktır. Aslında, şu anda her gün F # ve OCaml kullanıyorum ve bu dillerde kullandığım kalıplarla Java'da yazarken kullandığım kalıplar arasında çarpıcı bir fark yok.

Belki de hala zorla düşündüğünüz için? Birçok insan, tüm yaşamları boyunca zorunlu dillerle uğraştıktan sonra, işlevsel bir dil denediğinde bu alışkanlıktan vazgeçmekte zorlanıyor. (F # 'da oldukça komik girişimler gördüm, burada her fonksiyon tam anlamıyla bir C programı almış ve tüm noktalı virgülleri' let 'ile değiştirmiş gibi bir dizi' let 'deyimiydi. :))

Ancak başka bir olasılık, OOP dilinde tasarım kalıpları gerektiren sorunları önemsiz bir şekilde çözdüğünüzü fark etmemiş olabilirsiniz.

Currying kullandığınızda veya bir işlevi diğerine argüman olarak aktardığınızda, durun ve bunu OOP dilinde nasıl yapacağınızı düşünün.

İşlevsel programlamanın OOP tasarım modellerine olan ihtiyacı ortadan kaldırdığı iddiasına dair herhangi bir gerçek var mı?

Evet. :) Bir FP dilinde çalışırken, artık OOP'a özgü tasarım modellerine ihtiyacınız yoktur. Ancak yine de MVC veya OOP olmayan diğer spesifik öğeler gibi bazı genel tasarım desenlerine ihtiyacınız var ve bunun yerine birkaç yeni FP'ye özgü "tasarım desenine" ihtiyacınız var. Tüm dillerin eksiklikleri vardır ve tasarım kalıpları genellikle onların etrafında nasıl çalıştığımızdır.

Her neyse, elinizi ML (en azından öğrenme amacıyla kişisel favorim) veya Haskell gibi "daha temiz" FP dillerinde denemek ilginç olabilir , burada OOP koltuk değerine sahip değilseniz yeni bir şeyle karşı karşıyasınız.


Beklendiği gibi, birkaç kişi tasarım desenleri tanımımı "bir dilde eksiklikleri düzeltmek" olarak itiraz etti, bu yüzden burada benim gerekçem:

Daha önce de belirtildiği gibi, çoğu tasarım deseni bir programlama paradigmasına, hatta bazen belirli bir dile özgüdür. Genellikle, sadece bu paradigmada var olan problemleri çözerler (bkz. FP için monadlar veya OOP için soyut fabrikalar).

FP'de soyut fabrika deseni neden mevcut değil? Çünkü çözmeye çalıştığı sorun orada yok.

Dolayısıyla, FP dillerinde bulunmayan OOP dillerinde bir sorun varsa, bu açıkça OOP dillerinin eksikliğidir. Sorun çözülebilir, ancak diliniz bunu yapmaz, ancak etrafınızda çalışmak için bir grup demirbaş kodu gerektirir. İdeal olarak, programlama dilimizin tüm sorunları sihirli bir şekilde ortadan kaldırmasını istiyoruz. Hala var olan herhangi bir sorun prensip olarak dilin eksikliğidir. ;)


73
Tasarım örüntüleri temel sorunlara genel çözümleri tanımlar. Ancak programlama dilleri ve platformları da bunu yapar. Böylece, kullandığınız diller ve platformlar yeterli olmadığında tasarım kalıplarını kullanırsınız.
yfeldblum

135
S.Lott: Belirli bir dilde var olan sorunların çözümlerini açıklıyorlar, evet. FP dillerinde Komut tasarım deseni yoktur, çünkü çözmeye çalıştığı sorun mevcut değildir. Bu, dilin kendisinin çözemediği sorunları çözdükleri anlamına gelir. Yani, dildeki eksiklikler
jalf

38
Monad matematiksel bir kavramdır ve onu sınıflandırma ile uzatıyorsunuz. Elbette, fonksiyonları, monoidleri, monad'ları, matrisleri veya diğer matematiksel kavramları tasarım desenleri olarak görüntüleyebilirsiniz, ancak bunlar daha çok algoritmalar ve veri yapıları gibidir ... temel kavramlar, dilden bağımsız.
Alexandru Nedelcu

41
Tabii ki, monadlar bir matematik kavramdır, ama aynı zamanda bir kalıptır. Monadların "FP paterni" monadların matematik kavramından biraz farklıdır. Birincisi, saf FP dillerinde belirli "sınırlamaları" aşmak için kullanılan bir modeldir. İkincisi evrensel bir matematiksel kavramdır.
jalf

69
Haskell'deki monad'ların, istisnalar, devamlar, liste kavrayışları, ayrıştırma, eşzamansız programlama ve benzeri gibi değiştirilebilir durum dışındaki başka şeyler için kullanıldığını unutmayın. Ancak tüm bu monad uygulamalarına muhtemelen desen denilebilir.
JacquesB

152

İşlevsel programlamanın OOP tasarım modellerine olan ihtiyacı ortadan kaldırdığı iddiasına dair herhangi bir gerçek var mı?

Fonksiyonel programlama, nesne yönelimli programlama ile aynı değildir. Nesneye yönelik tasarım modelleri işlevsel programlama için geçerli değildir. Bunun yerine, işlevsel programlama tasarım modellerine sahipsiniz.

Fonksiyonel programlama için OO tasarım deseni kitaplarını okumazsınız; FP tasarım desenleriyle ilgili diğer kitapları okuyacaksınız.

agnostik dil

Tamamen değil. Yalnızca OO dillerine göre dil bilincine sahip değil. Tasarım örüntüleri prosedürel diller için hiç geçerli değildir. İlişkisel veritabanı tasarımı bağlamında zar zor anlaşılır. Bir e-tablo tasarlarken geçerli değildir.

tipik bir OOP tasarım modeli ve işlevsel eşdeğeri?

Yukarıdakiler olmamalıdır. Bu, OO kodu olarak yeniden yazılmış bir parça prosedür kodu istemek gibidir. Hımm ... Orijinal Fortran'ı (veya C'yi) Java'ya çevirirsem, çevirmekten başka bir şey yapmadım. Tamamen bir OO paradigmasına yeniden yazarsam, artık orijinal Fortran veya C gibi bir şey görünmeyecek - tanınmayacak.

OO tasarımından fonksiyonel tasarıma kadar basit bir eşleme yoktur. Soruna bakmak için çok farklı yollar.

Fonksiyonel programlama ( tüm programlama stilleri gibi ) tasarım desenlerine sahiptir. İlişkisel veritabanları tasarım örüntülerine, OO tasarım örüntülerine ve prosedürel programlama tasarım örüntülerine sahiptir. Her şeyin tasarım modelleri, hatta binaların mimarisi vardır.

Tasarım modelleri - bir kavram olarak - teknoloji ya da problem alanına bakılmaksızın, zamansız bir inşa yöntemidir. Ancak, belirli tasarım alanları belirli sorun alanları ve teknolojileri için geçerlidir.

Yaptıklarını düşünen herkes tasarım desenlerini ortaya çıkaracak.


12
MVC OO tasarımı değildir. Mimari tasarım - bu desen oldukça geniş bir şekilde uygulanır.
S.Lott

1
@Princess: fonksiyonel programlama mutlaka daha basit değildir. Örneğinizde, evet. Diğer şeyler için jüri hala dışarıda. Ancak bir Java OO tasarım desenini attınız ve bir FP tasarım desenini benimsediniz.
S.Lott

1
+1: Bu cevabı Jalf'ın yukarıdaki cevabına tercih ederim. Her ne kadar bazı tasarım modelleri dilde eksikliklere yönelik olsa da hepsi değil. Örneğin, "özyinelemeli düğümü çözme" tasarım modelinin dilde bir eksikliği giderdiğini söylemek zor, sadece bağımlılıkları gevşetmek için yararlı bir deyim.
Jon Harrop

9
Java 8, anonim işlevler, diğer adıyla lambda ifadeleri gibi kapanışları içerecektir. Bu, komut tasarım desenini Java için geçersiz kılacaktır. Bu dil eksikliğine bir örnek, değil mi? Eksik bir özellik eklediler ve şimdi tasarım desenine ihtiyacınız yok.
Todd Chaffee

2
Kapanış cümlesi için +1. Tasarım kalıpları, programlamayı basitleştirmek ve sonuçta ortaya çıkan programları, amaçlanan şekilde daha verimli kılmak içindir.
Sıralayıcı

46

Brian'ın dil ve örüntü arasındaki sıkı bağlantı hakkındaki yorumları,

Bu tartışmanın eksik kısmı deyim kavramıdır. James O. Coplien'in kitabı, "Advanced C ++" burada büyük bir etki yarattı. Christopher Alexander'ı ve İsimsiz Sütunu keşfetmeden çok önce (ve Alexander'ı okumadan kalıplar hakkında mantıklı bir şekilde konuşamazsınız), gerçekten bir dil öğrenmede deyimlere hakim olmanın öneminden bahsetti. Örnek olarak C'de dize kopyasını kullandı, while(*from++ = *to++);bunu eksik bir dil özelliği (veya kütüphane özelliği) için bir bandaj olarak görebilirsiniz, ancak bununla ilgili gerçekten önemli olan şey, bunun herhangi birinden daha büyük bir düşünce veya ifade birimi olmasıdır. parçaları.

Niyetlerimizi daha özlü bir şekilde ifade etmemize izin vermek için kalıpların ve dillerin yapmaya çalıştığı şey budur. Düşünce birimleri ne kadar zengin olursa, ifade edebileceğiniz düşünceler o kadar karmaşık olur. Sistem mimarisinden biraz burkulmaya kadar çeşitli ölçeklerde zengin, paylaşılan bir kelime dağarcığına sahip olmak, daha akıllı konuşmalar yapmamıza ve ne yapmamız gerektiğine dair düşüncelerimize izin veriyor.

Ayrıca bireyler olarak da öğrenebiliriz. Egzersizin tüm noktası budur. Hepimiz asla kendimiz hakkında düşünemeyeceğimiz şeyleri anlayabilir ve kullanabiliriz. Diller, çerçeveler, kütüphaneler, örüntüler, deyimler vb. Entelektüel zenginliği paylaşmadaki yeri vardır.


8
Teşekkür ederim! Bu desenler bilişsel yükünü düşürmek için hakkında- "kavramsal parçalama" ne olduğunu.
Randall Schulz

Ve Fonksiyonel Monadlar kesinlikle bu tartışmaya aittir.
Greg

@RandallSchulz: dil özellikleri (ve elbette deyimsel kullanımları) "bilişsel yükü azaltmak için kavramsal parçalama" kategorisine de uyuyor.
Roy Tinker

39

GoF kitabı açıkça OOP ile bağlanıyor - başlık Tasarım Desenleri - Yeniden Kullanılabilir Nesne Odaklı Yazılım Öğeleri (vurgu mayını).



26

İşte bu konuyu tartışan başka bir bağlantı: http://blog.ezyang.com/2010/05/design-patterns-in-haskel/

Edward, blog yazısında Haskell cinsinden 23 orijinal GoF modelini anlatıyor.


4
Makale, Haskell'deki tasarım desenlerini gerçekten göstermiyor gibi görünüyor, ancak Haskell'in bu ihtiyaçları nasıl ele aldığını söyleyen desenler olmadan gösteriyor.
Fresheyeball

3
@Fresheyball: Desen tanımınıza bağlıdır. Bir liste üzerinde bir işlev eşleştirmek Ziyaretçi düzeninin bir varyantı mıdır? Genel olarak cevabın "evet" olduğunu düşündüm. Kalıpların belirli bir sözdiziminin ötesine geçmesi beklenir. Uygulanan işlev bir nesne olarak sarılabilir veya bir işlev işaretçisi olarak iletilebilir, ancak kavram benim için aynıdır. Katılmıyor musunuz?
srm

20

Buna "tasarım örüntüleri" (genel olarak) ve "FP'ye karşı OOP" düzeyinde bakmaya çalıştığınızda, bulacağınız cevaplar en iyi şekilde karanlık olacaktır.

Bununla birlikte, her iki eksende daha derin bir seviyeye gidin ve belirli tasarım desenlerini ve belirli dil özelliklerini ve şeylerin daha net hale geldiğini düşünün .

Bu nedenle, örneğin, Ziyaretçi , Strateji , Komut ve Gözlemci gibi bazı özel desenler, cebirsel veri türlerine ve desen eşleşmesine , kapaklara , birinci sınıf işlevlere vb. Sahip bir dili kullanırken kesinlikle değişir veya kaybolur . GoF kitabındaki diğer bazı desenler hala Yine de 'takılmak'.

Genel olarak, zamanla, belirli kalıpların yeni (veya sadece popülaritesinde yükselen) dil özellikleriyle ortadan kaldırıldığını söyleyebilirim. Dil tasarımının doğal seyri budur; diller daha yüksek seviyeye geldikçe, daha önce yalnızca bir kitapta örnekler kullanılarak çağrılabilen soyutlamalar artık belirli bir dil özelliğinin veya kitaplığının uygulamaları haline gelmektedir.

(Bir yana: FP ve tasarım kalıpları hakkında daha fazla tartışmaya başka bağlantıları olan yazdığım son blog burada .)


Ziyaretçi kalıbının "kaybolduğunu" nasıl söyleyebilirsiniz? Sadece bir grup Ziyaret metoduyla Ziyaretçi arayüzü yapmaktan "birleşim türlerini ve kalıp eşleşmesini kullan" anlamına gelmiyor mu?
Gabe

22
Evet, ama bu bir kitapta okuduğunuz ve kodunuza uyguladığınız bir tasarım fikri olan bir kalıptan "sadece kod" olarak değişti . Yani, "birleşim türlerini ve kalıp eşleşmesini kullan", normalde böyle bir dilde şeyleri nasıl kodladığınızdır. (Analoji: Hiçbir dilde fordöngü yoksa ve hepsinde sadece whiledöngü varsa, o zaman "İçin" bir yineleme deseni olabilir. Ancak for, yalnızca dil tarafından desteklenen bir yapı ve insanların normal olarak nasıl kodlandıkları zaman, bu bir kalıp değildir; Bir desene ihtiyacım yok, sadece kod, adamım.)
Brian

4
Başka bir deyişle, belki de kötü değil bir turnusol testi "bu bir örüntüdür" için: şu anda kendi dilinizde bir yıllık deneyim programlama ile CS'de ikinci sınıf lisans öğrencisi bu şekilde yazılmış mevcut kod. Onlara kodu gösterirseniz ve "bu akıllı bir tasarım" a giderse, o zaman bir kalıptır. Onlara kodu gösterirseniz ve "iyi, duh!" (Ve bu "Ziyaretçi" bir yıl boyunca ML / F # / Haskell yapan herkese gösterirseniz, onlar "iyi, duh!")
Brian

1
Brian: Sanırım farklı bir "kalıp" tanımımız var. Ben olmak için herhangi bir tanımlanabilir tasarım soyutlama düşünün deseni bir olmak sadece sigara bariz soyutlamalar dikkate iken, desen . Sadece C # foreachve Haskell sahip mapMolduğu için Yineleyici desenleri olmadığı anlamına gelmez. Yineleyici desen IEnumerable<T>C # genel arabirimi ve TraversableHaskell typeclass olarak uygulandığını söylemek sorun görmüyorum .
Gabe

Belli olmayan kalıplar yazılım mühendisleri için yararlı olabilir, ancak tüm kalıplar dil tasarımcıları için yararlı olabilir. Yani "Yeni bir dil oluşturuyorsanız, yineleyici modelini ifade etmek için temiz bir yol eklediğinizden emin olun." "Bu fikri ifade etmek için daha iyi bir sözdizimi var mı?" Sorusunu sormaya başladığımızda bariz kalıplar bile ilgi çekicidir. Sonuçta, birisinin foreach oluşturmasına neden olan şey budur.
srm

16

Norvig'in sunumu, tüm GoF kalıpları üzerinde yaptıkları bir analizi ifade eder ve 23 kalıptan 16'sının işlevsel dillerde daha basit uygulamalara sahip olduğunu veya sadece dilin bir parçası olduğunu söylüyorlar. Yani muhtemelen en azından yedisi ya a) eşit derecede karmaşıktı ya da b) dilde mevcut değildi. Ne yazık ki bizim için numaralandırılmıyorlar!

GoF'taki "yaratıcı" veya "yapısal" modellerin çoğunun, istediğiniz şeyi yapmak için Java veya C ++ 'da ilkel tip sistemleri elde etmek için sadece hileler olduğunu düşünüyorum. Ancak geri kalanı hangi dilde programladığınız önemli değil.

Bunlardan biri Prototip olabilir; JavaScript'in temel bir kavramı olsa da, diğer dillerde sıfırdan uygulanması gerekir.

En sevdiğim kalıplardan biri Boş Nesne kalıbı: uygun bir şey yapmayan bir nesne olarak bir şeyin yokluğunu temsil eder. İşlevsel bir dilde modelleme yapmak daha kolay olabilir. Ancak, gerçek başarı perspektifteki değişimdir.


2
GoF kalıplarından bu yana yapılması gereken tuhaf bir analiz, sınıf temelli OOP dilleri için özel olarak tasarlanmıştır. Biraz boru anahtarlarının elektrik işleri için iyi olup olmadığını analiz etmek gibi görünüyor.
munificent

@munificent: Pek değil. Nesne yönelimi polimorfizm sağlar; fonksiyonel programlama genellikle polimorfizm sağlar.
Marcin

@Marcin bir OO programcısı polimorfizm tarafından fonksiyonel bir programcıdan çok farklı bir şey ifade eder.
AndrewC

@AndrewC Kabul etmiyorum. OO programcısı farklı bir şey ifade ettiklerini düşünebilir, ama istemezler.
Marcin

3
@Marcin Deneyimlerime göre, bir OO programcısı tipik olarak alt tip polimorfizmden (genellikle sadece Object kullanarak), bunu elde etmek için dökümler veya geçici polimorfizmden (aşırı yükleme vb.) Bahsediyor. Fonksiyonel bir programcı polimorfizm derken , OO programcılarının genellikle polimorfizm olarak adlandırdığı herhangi bir şeyden daha çok OO'nun jenerik programlamasına benzeyen parametrik polimorfizm (yani her türlü veri için çalışır - Int, fonksiyon, liste).
AndrewC

15

Makro desteği ile Lisp gibi bir diliniz olduğunda, genellikle genel deyim çözümlerinden çok daha iyi olan kendi alan adına özgü soyutlamalar, soyutlamalar oluşturabileceğinizi söyleyebilirim.


Tamamen kayboldum. Soyutlamalarla bir şeyler yapmak ... Bu ne anlama geliyor?
tuinstoel

2
Makro olmadan etki alanına özgü soyutlamalar (katıştırılmış olanlar da dahil) oluşturabilirsiniz. Makrolar, özel sözdizimi ekleyerek onları güzelleştirmenize izin verir.
Jon Harrop

2
Lisp'i programlama dilleri oluşturmak için bir dizi Legos olarak düşünebilirsiniz - bu bir dil ama aynı zamanda bir meta dildir. Bu, herhangi bir sorun alanı için, belirgin bir eksikliği olmayan bir dili özel olarak tasarlayabileceğiniz anlamına gelir. Biraz pratik gerektirecek ve Kurt Gödel buna katılmayabilir, ancak Lisp ile masaya ne getirdiğini görmek için biraz zaman ayırmaya değer (ipucu, makrolar).
Greg

9

Hatta OO tasarım deseni çözümleri bile dile özgüdür.

Tasarım kalıpları, programlama dilinizin sizin için çözmediği yaygın sorunlara çözümlerdir. Java'da, Singleton deseni bir şeyden (basitleştirilmiş) sorunu çözer.

Scala'da, Class'a ek olarak Object adında bir üst düzey yapınız var. Tembel bir şekilde başlatılır ve sadece bir tane vardır. Dilin bir parçası.


8

Desenler, tekrar tekrar görülen ve daha sonra tarif edilen ve belgelenen benzer sorunları çözmenin yoludur. Yani hayır, FP kalıpların yerini almayacak; ancak, FP yeni modeller oluşturabilir ve bazı güncel "en iyi uygulamaları" modelleri "geçersiz kılabilir".


4
GoP kalıpları, yolunuza çıkan belirli bir programlama dilinin sınırlamaları sorununu çözmenin yollarıdır. Örneğin, "Sınıfları dolaylı olarak kullanmak ve onlara nesne yapmalarını söylemek istiyorum" -> "Yapamazsınız, ancak Fabrika adı verilen metasınıf benzeri nesneler yapabilirsiniz". "Birden fazla sevkiyat istiyorum" -> "Yapamazsınız, ancak Ziyaretçi Kalıbı adı verilen bir labirent var". Vb Belirli sınırlamalar olan bir OOP dilinde değilseniz, kalıpların hiçbiri anlamlı değildir.
Kaz

1
Bunların hiçbirinin diğer dillerde anlam ifade etmediğini bilmiyorum, ancak çoğunun diğer dillerde anlam ifade etmediğini kabul edeceğim. Bağdaştırıcı ve Köprü, çok dilli olasılıklara sahip gibi görünüyor, ziyaretçi için biraz, belki de dinleyici için biraz daha az. Bununla birlikte, diller arasındaki kalıplar her zaman dilin doğal sınırlarını destekleyen "X dilinin Y dilinde işleyişi nasıl yapılır" türünden muzdarip olacaktır. Mükemmel bir örnek Singleton modeliydi, yani temelde OOP'ta C globallerini nasıl edinebilirim? (ki cevaplayacağım, yapmamalısın).
Edwin Buck

1
İkinci Kaz: Kalıp, "tekrar tekrar görülen benzer problemleri çözmenin bir yolu" değil, "tekrar tekrar görülen benzer sorunları çözmenin bir yoludur VE tekrar tekrar yazılması gerekir çünkü dil, sadece bir kez yaz ". Diğer bir deyişle, eğer dil, kütüphane / sınıf / modül vb. İçinde örüntünün çıkarılmasına / soyutlanmasına izin verdiyse, örüntü olmayı durdurur ancak kütüphane / sınıf / modül haline gelir. FP'de, bir işleve kod bitlerini çıkarmak / soyutlamak çok daha kolaydır, bu nedenle "desen" yeniden kullanılabilir kodda daha kolay dönüştürülür ve bu da bir desen değildir.
mb14

1
Yorumunuz açıktır, ancak GoF kitabı bir desen tanımlamak için açıktı ve giriş bölümlerini okuduysanız, diller veya dilin zayıf yönleri hakkında hiçbir şey söylemiyor. Kuşkusuz bazı diller, bazı kalıpları daha sık kullanmalarını sağlayacak alanlara sahiptir, ancak on kez yazıp (kesip yapıştır) veya on gerçekleştirme (alt sınıflandırma) ile bir kez uygulayıp uygulamadığınız veya biraz on yapacak şekilde yapılandırılmış bir çerçeveye sahip olun farklı yollar, sadece ortaya çıkan modelin uygulama detayıdır.
Edwin Buck

1
Yıllar sonra bu sohbete geri döndüğümde, birçok insanın Desenleri belirli bir programlama dili veya belirli bir programlama paradigması ile ilişkilendirdiğini düşünüyorum. Böyle bir bağlamda kullanılabilirler, ancak programlamadan önce vardı. "Zamansız bir inşa yöntemi" mimarlık ve toplum planlaması inşa etme meselelerini tartışıyor. Bu, yapıya bir programlama dili çağırmak istemediğiniz sürece, desen yönelimli tekniklerin "bir dilin sınırlamaları" dışında kullanılabileceği anlamına gelir :)
Edwin Buck

8

Diğerlerinin söylediği gibi, fonksiyonel programlamaya özgü paternler vardır. Tasarım kalıplarından kurtulma meselesinin işlevselliğe geçme meselesi değil, dil özellikleri meselesi olduğunu düşünüyorum .

Scala'nın "tek tonlu desen" ile nasıl başardığına bir göz atın: bir sınıf yerine bir nesneyi beyan edersiniz . Başka bir özellik, desen eşleştirme, ziyaretçi deseninin becerikliliğinden kaçınmaya yardımcı olur. Buradaki karşılaştırmaya bakın: Scala'nın Kalıp Eşleşmesi = Steroidler Üzerinde Ziyaretçi Kalıbı

Ve Scala, F # gibi, OO-işlevselliğinin bir birleşimidir. F # hakkında bilmiyorum, ama muhtemelen bu tür özelliklere sahip.

Kapaklar işlevsel dilde mevcuttur, ancak bunlarla sınırlı olmaları gerekmez. Delege düzenine yardımcı olurlar.

Bir gözlem daha. Bu kod parçası bir desen uygular: öyle bir klasik ve o kadar basittir ki, bunu genellikle bir "desen" olarak düşünmüyoruz, ama kesin:

for(int i = 0; i < myList.size(); i++) { doWhatever(myList.get(i)); }

Java ve C # gibi zorunlu diller temel olarak bununla başa çıkmak için işlevsel bir yapı olan “foreach” i benimsemiştir.


Scala'nın tekil kalıp için birinci sınıf destek içerdiğini söyleyebilirim. Kalıp hala orada, ancak kalıbı uygulamak için gereken kaynak plakası kodu Java'ya kıyasla büyük ölçüde azalıyor.
JacquesB

Eğer fikirler bir şey gibi olsaydı, ... Cevapların geri kalanına bakın. "sadece bir sınıf yerine bir nesne beyan" çok doğru, ben açıkça açıkça bir nesne olarak adlandırmak (yani var singleton = {};). Ben de foreach modelinden bahsetmeyi seviyorum. Ne yazık ki, bu soruya cevap veren / yorum yapan insanların çoğu fonksiyonel programlamayı anlamıyor ve OOP tasarım modellerinin kullanımını haklı çıkarıyor gibi görünüyor. Somut örnekler sunmak için +1, yapabilseydim daha fazla verirdim.
Evan Plaice

@JacquesB Scala / Haskell hakkında yorum yapamıyorum ama JavaScript'te (örn. Hibrit fonksiyonel / zorunlu) kesinlikle hiçbir nesne plakası yok, sadece nesne değişmez sözdizimi, anonim işlevler kombinasyonlarını kullanarak nesneleri bildirme şeklinizi ayarlıyorsunuz sınıf üyeleri ve birden fazla mirasa izin verilmesi (arayüz sözleşmesi ihtiyacını ortadan kaldırmak).
Evan Plaice

8

GoF Tasarım Desenleri , Simula 67'nin torunları olan OO dilleri için Java ve C ++ gibi geçici tarifleri kodlamaktadır .

Tasarım desenleri tarafından tedavi edilen "hastalıklar" ın çoğu şunlardan kaynaklanır:

  • nesneleri belirten ancak kendileri nesne olmayan statik olarak yazılan sınıflar;
  • tek dağıtma kısıtlaması (bir yöntem seçmek için yalnızca en soldaki bağımsız değişken kullanılır, kalan bağımsız değişkenler yalnızca statik türler olarak kabul edilir: dinamik türler varsa, bunu geçici yaklaşımlarla sıralamak için bir yöntemdir);
  • normal işlev çağrıları ile nesne yönelimli işlev çağrıları arasındaki ayrım; diğer bir deyişle nesne yönelimli işlevler, normal işlevlerin beklendiği yerlerde işlevsel bağımsız değişken olarak iletilemez; ve
  • "temel türler" ve "sınıf türleri" arasındaki ayrım.

Çözüm temel olarak karşılık gelen tasarım deseniyle aynı şekilde yapılandırılmış olsa da, Ortak Lisp Nesne Sisteminde kaybolmayan bu tasarım modellerinden tek bir tane yoktur. (Dahası, bu nesne sistemi GoF kitabından on yıldan fazla bir süre önce gelir. Common Lisp, bu kitabın ilk yayınlandığı yıl bir ANSI standardı oldu.)

Fonksiyonel programlama söz konusu olduğunda, örüntülerin ona uygulanıp uygulanmayacağı, verilen fonksiyonel programlama dilinin bir çeşit nesne sistemine sahip olup olmamasına ve örüntülerden yararlanan nesne sistemlerinden sonra modellenip modellenmemesine bağlıdır. Bu tür bir nesne yönelimi işlevsel programlama ile iyi karışmaz, çünkü durum mutasyonu ön ve merkezdedir.

İnşaat ve mutasyona uğramayan erişim işlevsel programlama ile uyumludur ve bu nedenle soyutlama erişimi veya inşaat ile ilgili olan desenler uygulanabilir: Fabrika, Cephe, Proxy, Dekoratör ve Ziyaretçi gibi desenler.

Diğer yandan, Devlet ve Strateji gibi davranış kalıpları muhtemelen işlevsel OOP'da doğrudan uygulanmaz, çünkü devletin mutasyonu özünde yer alır. Bu, başvurmadıkları anlamına gelmez; belki de bir şekilde değişebilir durumu simüle etmek için mevcut olan hilelerle birlikte uygulanırlar.


2
"GoF Tasarım Desenleri geçici tarifleri kodlamaktadır" sadece yanlış bir ifadedir.
John Peters

7

Jeremy Gibbons'ın birkaç mükemmel ama biraz yoğun makalesini eklemek istiyorum: "Üst düzey veri tipi-jenerik programlar olarak tasarım modelleri" ve "Yineleyici modelinin özü" (her ikisine de buradan ulaşabilirsiniz: http: // www. comlab.ox.ac.uk/jeremy.gibbons/publications/ ).

Her ikisi de deyimsel fonksiyonel yapıların diğer (nesne yönelimli) ortamlarda belirli tasarım desenlerinin kapsadığı araziyi nasıl kapsadığını açıklar.


6

Bu tartışmayı tip sistemleri getirmeden yapamazsınız.

Fonksiyonel programlamanın temel özellikleri arasında birinci sınıf değerler, körelme, değişmez değerler vb. Gibi fonksiyonlar bulunmaktadır. OO tasarım modellerinin bu özelliklerden herhangi birine yaklaştığı açık değildir.

Çünkü bu özellikler OOP ile aynı sorunları ele almıyor ... zorunlu programlamaya alternatifler. OOP'a verilen FP cevabı, ML ve Haskell'in tip sistemlerinde yatmaktadır ... özellikle toplamlar, soyut veri tipleri, ML modülleri ve Haskell tip sınıfları.

Ama elbette FP dilleri tarafından çözülmeyen tasarım desenleri hala var. Singleton'un FP eşdeğeri nedir? (Singletonların genellikle korkunç bir model olduğunu bir an için dikkate almamak)

Tipik sınıfların yaptığı ilk şey singleton ihtiyacını ortadan kaldırmaktır.

23 listesini gözden geçirebilir ve daha fazlasını ortadan kaldırabilirsiniz, ama şu anda zamanım yok.


6
Daktilo sınıfları (OOP arayüzlerinin FP eşdeğeri) tekil (global durumun FP eşdeğeri) ihtiyacını nasıl ortadan kaldırır?
Gabe

4

Bence işlevsel programlama mantığını doğal OO diline tanıtmak için sadece iki GoF Tasarım Deseni tasarlandı. Strateji ve Komuta'yı düşünüyorum. Diğer GoF tasarım modellerinden bazıları, tasarımı basitleştirmek ve amacı korumak için fonksiyonel programlama ile değiştirilebilir.


4
Şey, birçok modelin ana noktası, FP kavramlarına iyi bir desteğin otomatik olarak izin verebileceği şeyleri yapmak için polimorfizmi kullanmaktır. (Örneğin, Builder'ı gördüğüm çoğu enkarnasyon sadece yarı kıvrımlıdır.) İşlevleri kolayca değer olarak ele alabildiğinizde, desenler genellikle önemsizliğe kadar basitleşir. "Geri arama" veya "geri arama sözlüğü" haline gelirler ve örneğin farklı oluşturucu sınıfları kaybolabilir. IMO bir desen , uygulamanız gereken bir şeyden ziyade işlerin nasıl çalıştığı kadar önemsiz olduğunda desen olmayı durdurur .
cHao


3

Fonksiyonel programlama tasarım desenlerinin yerini almaz. Tasarım desenleri değiştirilemez.

Desenler basitçe vardır; zamanla ortaya çıktılar. GoF kitabı bazılarını resmileştirdi. Geliştiriciler heyecan verici şeyler olan işlevsel programlama dillerini kullandıkça yeni modeller ortaya çıkarsa ve belki de onlar hakkında yazılmış kitaplar olacaktır.


1
Tasarım kalıpları değiştirilemez mi? Bu biraz kapalı fikirli bence. Muhtemelen hepimiz tasarım modellerinin programlama problemlerini çözmek için olduğunu kabul edebiliriz ve en azından bir gün bu problemleri tasarım desenleri olmadan çözebileceğimizi ummak isterim.
Metropolis

3
Herhangi bir özel kalıp değiştirilebilir, ancak kalıp kavramı yapılamaz. "Desen" teriminin mimarlıkta ortaya çıktığını unutmayın .
Frank Shearar

1
Kalıplar programlama problemlerini çözmek için tasarlanmamıştır. Desenler programladığımız yollardır. Kalıpların dokümantasyonu, programlama problemlerinin çözülmesine yardımcı olmak içindir.
Torbjørn

3
@ Torbjørn: Desenler , dil engellendiğinde programladığımız yöntemlerdir . Bunlar, programın istenen davranışı ile dilin yerleşik yetenekleri arasında, gereksinimlerin ve yeteneklerin iyi eşleşmediği veya belirsiz bir şekilde eşleşmediği bazı uyumsuzluklar nedeniyle mevcuttur. Eğer böyle olmasaydı, desen olmazdı; Sadece tek kişi uygulanmasını olurdu işlerin nasıl ve diğer uygulamalar etkin bir düşünmediğini değer olacaktır.
cHao

1
Ancak kalıplar gerçekten sadece iletişimi kolaylaştırmak için var olur. Başka bir amacı yok. Yıllar boyunca katıldığım tüm tasarım toplantılarında, algoritmanın tartışılması kalıp değil önemli olan şeydi. Desen nadiren anlamlı bir anlamda gerçekte neler olduğunu açıkladı. O (n) ve O (n Log (n)) etkilerini tam olarak açıklıyor mu? Hayır. Mevcut mimariye ne kadar kolay uyacağını açıklıyor mu? Hayır. Tam ölçekli algoritma tartışmaları yapar. Ben kalıpların kendi başına emekliye ayrılması gerektiğini savunmuyorum, ama eğer olsaydı sonuç olarak neredeyse hiçbir şey zarar görmezdi.

3

"Scala ve Clojure'da" Fonksiyonel Programlama Desenleri- " adlı yeni 2013 kitabında yazar Michael.B. Linn, GoF desenleri için birçok durumda karşılaştırma ve değiştirme sağlayan iyi bir iş yapar ve ayrıca 'kuyruk özyineleme', 'hatırlama', 'tembel dizi' vb.

Bu kitap Amazon'da mevcut. Birkaç on yıllık bir OO geçmişinden geldiğinde çok bilgilendirici ve cesaret verici buldum.


3

OOP ve GoF modelleri devletlerle ilgilenir. OOP, kod tabanını verilen gerçeklik gereksinimlerine olabildiğince yakın tutmak için gerçeği modeller. GoF tasarım kalıpları, atomik gerçek dünya problemlerini çözmek için tanımlanan kalıplardır. Devlet sorununu anlamsal bir şekilde ele alırlar.

Gerçek fonksiyonel programlamada olduğu gibi hiçbir durum yoktur, GoF modellerini uygulamak mantıklı değildir. GoF tasarım desenleri ile aynı şekilde fonksiyonel tasarım desenleri yoktur. Her işlevsel tasarım deseni gerçekliğin aksine yapaydır, çünkü işlevler gerçekliğin değil matematiğin yapılarıdır.

Fonksiyonlar zaman kavramından yoksundur, çünkü zaman "gelecekteki talepleri" önceden işlemeyi gerçekten zorlaştıran fonksiyon parametrelerinin bir parçası olmadığı sürece şimdiki zaman ne olursa olsun aynı değeri döndürür. Karma diller bu kavramları karıştırır ve dilleri gerçek işlevsel programlama dilleri haline getirmez.

İşlevsel diller sadece bir şey yüzünden yükseliyor: fiziğin mevcut doğal kısıtlamaları. Günümüzün işlemcileri, fiziksel yasalar nedeniyle işlem yönergelerinin hızıyla sınırlıdır. Saat frekansında bir durgunluk, ancak işlem çekirdeğinde bir genişleme görüyorsunuz. Bu nedenle modern uygulamaların hızını arttırmak için talimatların paralelliği gittikçe daha önemli hale geliyor. Tanım gereği fonksiyonel programlamanın bir durumu olmadığı ve bu nedenle yan etkileri olmadığı için işlevleri paralel olarak güvenle işlemek güvenlidir.

GoF kalıpları kullanılmıyor. En azından gerçek dünya gereksinimlerini modellemek için gereklidirler. Ancak işlevsel bir programlama dili kullanıyorsanız, bunları melez eşdeğerlerine dönüştürmeniz gerekir. Son olarak, kalıcılığı kullanırsanız sadece fonksiyonel programlar yapma şansınız yoktur. Programınızın hibrit öğeleri için GoF kalıplarını kullanma gereği devam etmektedir. Tamamen işlevsel olan diğer herhangi bir eleman için GoF kalıplarını kullanmaya gerek yoktur çünkü durum yoktur.

GoF modelleri gerçek fonksiyonel programlama için gerekli olmadığından, SOLID ilkelerinin uygulanmaması gerektiği anlamına gelmez. SOLID ilkeleri herhangi bir dil paradigmasının ötesindedir.


2
FP devlete sahip olabilir - sadece küresel, paylaşılan veya değişebilir bir devlet yoktur.
vt5491

2

Fonksiyonel programlamada tasarım kalıplarının farklı bir anlamı vardır. Aslında, OOP tasarım modellerinin çoğu, daha yüksek soyutlama seviyesi ve yapı taşları olarak kullanılan HOF'ler nedeniyle fonksiyonel programlamada gereksizdir .

HOF ilkesi, işlevlerin diğer işlevlere argüman olarak iletilebileceği anlamına gelir. ve fonksiyonlar değer döndürebilir.


1

Kabul edilen cevabın dediği gibi, OOP ve FP'nin kendine özgü kalıpları vardır.

Bununla birlikte, aklıma gelen tüm programlama platformlarının sahip olması gerektiği kadar yaygın olan bazı desenler vardır. İşte (eksik) bir liste:

  • Adaptör. Dünyayla konuşmaya gerek duymayacak kadar kapsamlı (ve kendi kendini gerçekleştiren) kullanışlı bir programlama platformu düşünemiyorum. Bunu yapacaksa, kesinlikle bir adaptöre ihtiyaç vardır.

  • Cephe. Büyük kaynak kodunu işleyebilen tüm programlama platformları modüler hale getirilebilmelidir. Programın diğer bölümleri için bir modül oluşturursanız, kodun "kirli" bölümlerini gizlemek ve hoş bir arayüz vermek istersiniz.

  • Tercüman. Genel olarak, herhangi bir program sadece iki şey yapar: girdi ve çıktıları ayrıştır. Fare girişlerinin ayrıştırılması ve pencere widget'larının yazdırılması gerekir. Bu nedenle, gömülü bir tercümana sahip olmak, programa işleri özelleştirmek için ek güç verir.

Ayrıca, tipik bir FP dilinde, Haskell'de, GoF modellerine benzer, ancak farklı isimlerle bir şey olduğunu fark ettim. Benim düşünceme göre bu, orada olduklarını gösteriyor çünkü hem FP hem de OOP dillerinde çözülmesi gereken bazı ortak sorunlar var.

  • Monad transformatör ve dekoratör. Birincisi mevcut bir monad'a ek yetenek eklemek için kullanılırken, ikincisi mevcut bir nesneye ek yetenek ekler.

1

Her paradigmanın farklı bir amaca hizmet ettiğini ve bu şekilde karşılaştırılamayacağını düşünüyorum.

GoF tasarım modellerinin her dile uygulanabilir olduğunu duymadım. Tüm OOP dilleri için geçerli olduklarını duydum . İşlevsel programlama kullanıyorsanız, çözdüğünüz sorunların etki alanı OO dillerinden farklıdır.

Bir kullanıcı arabirimi yazmak için işlevsel dili kullanmazdım, ancak C # veya Java gibi OO dillerinden biri bu işi kolaylaştırır. İşlevsel bir dil yazsaydım, OO tasarım kalıplarını kullanmayı düşünmezdim.


1

OOP ve FP'nin farklı hedefleri var. OOP, yazılım bileşenlerinin karmaşıklıklarını / hareketli parçalarını kapsüllemeyi ve FP, yazılım bileşenlerinin karmaşıklığını ve bağımlılıklarını en aza indirmeyi amaçlamaktadır.

Bununla birlikte, bu iki paradigma% 100 ile çelişmek zorunda değildir ve her iki dünyadan faydalanmak için birlikte uygulanabilir.

C # gibi işlevsel programlamayı yerel olarak desteklemeyen bir dilde bile, FP ilkelerini anlarsanız işlevsel kod yazabilirsiniz. Aynı şekilde, OOP ilkelerini, modellerini ve en iyi uygulamaları anlarsanız, F # kullanarak OOP ilkelerini uygulayabilirsiniz. Kullandığınız programlama dilinden bağımsız olarak çözmeye çalıştığınız duruma ve soruna göre doğru seçimi yaparsınız.


1

FP'yi destekleyen bir dilde bazı kalıpların uygulanması daha kolaydır. Örneğin, Strateji güzelce kapanışlar kullanılarak uygulanabilir. Ancak bağlama bağlı olarak, Strateji'yi sınıf tabanlı bir yaklaşım kullanarak uygulamayı tercih edebilirsiniz, stratejilerin kendilerinin oldukça karmaşık olduğu ve / veya Şablon Yöntemi'ni kullanarak modellemek istediğiniz yapıyı paylaşın.

Çok paradigmalı bir dilde (Ruby) geliştirme deneyimime göre, FP uygulaması basit durumlarda iyi çalışır, ancak bağlamın daha karmaşık olduğu durumlarda, GoF OOP tabanlı yaklaşım daha uygundur.

FP yaklaşımı OOP yaklaşımının yerini almaz, onu tamamlar.


0

Fonksiyonel programlamanın en önemli özelliği olan IMHO, hiçbir şey olmadan programlama yapmanızdır. ifadelerden - ifadeler içindeki ifadeler içinde "hepsi değerlendirildiğinde makineyi ısıtan" son, son ifadeye göre değerlendirilen ifadelerdir.

Nesne yönelimli programlamanın en önemli özelliği olan IMHO, dahili duruma sahip nesnelerle programlama yapmanızdır. Saf işlevlerde dahili duruma sahip olamazsınız - nesne yönelimli programlama dilleri ifadelere ihtiyaç duyar şeyleri gerçekleştirmek için . (Fonksiyonel programlamada ifade yoktur.)

Elmaları portakallarla karşılaştırıyorsunuz. Nesne yönelimli programlama örüntüleri fonksiyon programlama için geçerli değildir, çünkü fonksiyonel programlama ifadelerle programlama ve nesne yönelimli programlama dahili durum ile programlamadır.


Hmm, cevap vermeden önce sorunun on bir yaşında olduğunu fark etmeliydim. :-)
Jim Flood

0

Kendinizi hazırlayın.

Tasarım desenlerinin yerini aldığımı ve SOLID ve DRY'yi çıkardığımı iddia ettiğimi duymak pek çok kişiyi ağırlaştırıyor. Ben hiç kimseyim. Yine de, işbirlikçi (imalat) mimariyi doğru bir şekilde modelledim ve arkasındaki kod ve bilimle birlikte çevrimiçi süreçler oluşturma kurallarını web sitemde yayınladım http://www.powersemantics.com/ .

Benim iddiam, tasarım örüntülerinin, her adımın yeniden şekillendirilebileceği, yeniden şekillendirilebileceği ve genişletilebileceği bir süreç olan üretimin "kitlesel özelleştirme" olarak adlandırdığı şeye ulaşmaya çalışmasıdır. Bu tür işlemleri derlenmemiş komut dosyaları olarak düşünebilirsiniz. Burada (çevrimiçi) argümanımı tekrarlamayacağım. Kısacası, toplu özelleştirme mimarim, dağınık anlambilim olmadan bu esnekliği elde ederek tasarım modellerinin yerini alıyor. Modelimin çok iyi çalıştığına şaşırdım, ancak programcıların kod yazma şekli, üretimin işbirlikçi işi nasıl organize ettiğine dair bir mum tutmuyor.

  • Üretim = her adım bir ürünle etkileşime girer
  • OOP = her adım, kendisi ve diğer modüller ile etkileşime girerek ürünü işe yaramaz ofis çalışanları gibi bir noktadan diğerine geçirir

Bu mimarinin hiçbir zaman yeniden düzenlemeye ihtiyacı yoktur. Merkezileşme ve dağıtım ile ilgili olarak karmaşıklığı etkileyen kurallar da vardır. Ancak sorunuzu cevaplamak için, işlevsel programlama, kitle özel süreçleri için bir mimari değil, başka bir işlem semantiği setidir; 1) kaynak yönlendirmesi, wielder'ın ateşlemeden önce yeniden yazabileceği ve 2) modüllerin kolayca ve dinamik olarak eklendi veya kaldırıldı.

OOP'un "kodlanmış süreç" paradigması olduğunu ve tasarım modellerinin bu paradigmadan kaçınmanın yolları olduğunu söyleyebiliriz. Ama kitlesel özelleştirmenin amacı budur. Tasarım desenleri, dinamik süreçleri dağınık sabit kod olarak somutlaştırır. Bir anlamı yok. F # işlevlerinin parametre olarak geçmesine izin vermesi , işlevsel ve OOP dillerinin aynı zamanda kitlesel özelleştirmeyi kendisi gerçekleştirme girişimi anlamına gelir .

Komut dosyasını temsil eden sabit kod okuyucu için ne kadar kafa karıştırıcı? Derleyicinizin tüketicilerinin böyle özellikler için ödeme yaptığını düşünüyorsanız, ancak bana göre bu özellikler semantik atıklardır. Kitle özelleştirme noktası süreçlerini kendileri yapmaktır, çünkü anlamsız dinamik Visual Studio wielding programcıya, sadece dinamik.


0

Üst düzey bir fonksiyonel PL'nin (OCaml gibi, sınıflar, modüller vb.), Tip çok yönlülüğü ve ifade gücünde kesinlikle OOP zorunluluklarının yerini alır. Soyutlamalar sızmaz, fikirlerinizin çoğunu doğrudan programda ifade edebilirsiniz. Bu nedenle, evet, çoğu fonksiyonel desenle karşılaştırıldığında gülünç derecede basit olan tasarım desenlerinin yerini alıyor.

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.