Sınıflarla OOP'a kıyasla fonksiyonel programlama


32

Son zamanlarda bazı fonksiyonel programlama kavramlarıyla ilgileniyorum. OOP'u bir süredir kullandım. OOP'ta oldukça karmaşık bir uygulamayı nasıl oluşturacağımı görebiliyorum. Her nesne, o nesnenin nasıl yapılacağını bilirdi. Ya da ebeveyn sınıfının yaptığı gibi. Böylece Person().speak()insanı konuşturmasını söyleyebilirim .

Fakat işlevsel programlamada benzer şeyleri nasıl yaparım? İşlevlerin birinci sınıf öğeler olduğunu görüyorum. Ancak bu işlev yalnızca belirli bir şey yapar. say()Etrafında kayan bir yöntemim olur mu ve buna eşdeğer bir Person()argüman olarak adlandırırdım, böylece ne tür bir şey söylediğini biliyorum?

Böylece basit şeyleri görebiliyorum, işlevsel programlamada OOP ile nesnelerin karşılaştırılabilirliğini nasıl yapabilirim, böylece kod tabanımı modülerleştirebilir ve düzenleyebilirim?

Başvuru için OOP konusundaki temel deneyimim Python, PHP ve C #. Baktığım diller fonksiyonel özelliklere sahip. Scala ve Haskell. Scala'ya doğru eğildim.

Temel Örnek (Python):

Animal(object):
    def say(self, what):
        print(what)

Dog(Animal):
    def say(self, what):
        super().say('dog barks: {0}'.format(what))

Cat(Animal):
    def say(self, what):
        super().say('cat meows: {0}'.format(what))

dog = Dog()
cat = Cat()
dog.say('ruff')
cat.say('purr')

Scala OOP + FP olarak tasarlanmıştır, bu yüzden seçmek zorunda değilsiniz
Karthik T

1
Evet farkındayım, ama aynı zamanda entelektüel nedenlerle de bilmek istiyorum. Nesnelerin eşdeğerinde işlevsel dillerde hiçbir şey bulamıyorum. Ölçek olarak, ne zaman / nerede / nasıl oop'ta işlevsel olarak kullanmam gerektiğini bilmek isterdim, ancak IMHO'nun başka bir soru olduğunu söyleyebilirim.
12'de

2
“Özellikle aşırı vurgulanan IMO, devleti korumamamız gerektiği kavramıdır”: Bu yanlış bir kavramdır. FP'nin durumu kullanmadığı doğru değildir, FP durumu farklı şekilde ele alır (örneğin Haskell'deki monadlar veya Clean'deki benzersiz türler).
Giorgio


Yanıtlar:


21

Burada gerçekte sorduğunuz şey, polimorfizmi işlevsel dillerde nasıl yapacağınızı, yani onların argümanlarına göre farklı davranış gösteren işlevleri nasıl yaratacağınızdır.

Bir fonksiyonun ilk argümanının tipik olarak OOP'daki "nesne" ye eşittir, ancak işlevsel dillerde genellikle işlevleri veriden ayırmak istersiniz, bu nedenle "nesne" nin saf (değişmez) bir veri değeri olması muhtemeldir.

Genel olarak fonksiyonel diller, polimorfizmi sağlamak için çeşitli seçenekler sunar:

  • Sağlanan argümanları incelemeye dayanarak farklı bir işlev çağıran multimethods gibi bir şey . Bu, ilk argüman türü üzerinde yapılabilir (bu, çoğu OOP dilinin davranışına etkili bir şekilde eşittir), ancak aynı zamanda argümanların diğer özellikleri üzerinde de yapılabilir.
  • Birinci sınıf işlevleri içeren prototip / nesne benzeri veri yapıları . Böylece, köpek ve kedi veri yapılarınızın içine "say" işlevini gömebilirsiniz. Etkili bir şekilde kodu verilerin bir parçası haline getirdiniz.
  • Örüntü eşleme - örüntü eşleme mantığının işlev tanımında yerleşik olduğu ve farklı parametreler için farklı davranışlar sağladığı yerlerde. Haskell'de yaygın.
  • Dallanma / koşullar - OOP içindeki if / else maddelerine eşdeğer. Çok genişletilebilir olmayabilir, ancak sınırlı sayıda olası değere sahip olduğunuzda yine de uygun olabilir (örneğin, işlev bir sayı veya bir dizge veya boş mu geçirilmiş?)

Örnek olarak, burada çoklu metotları kullanarak probleminizin Clojure uygulaması:

;; define a multimethod, that dispatched on the ":type" keyword
(defmulti say :type)  

;; define specific methods for each possible value of :type. You can add more later
(defmethod say :cat [animal what] (println (str "Car purrs: " what)))
(defmethod say :dog [animal what] (println (str "Dog barks: " what)))
(defmethod say :default [animal what] (println (str "Unknown noise: " what)))

(say {:type :dog} "ruff")
=> Dog barks: ruff

(say {:type :ape} "ook")
=> Unknown noise: ook

Bu davranışın tanımlanacak açık sınıflar gerektirmediğini unutmayın: normal haritalar iyi çalışır. Gönderim işlevi (: bu durumda yazın) bağımsız değişkenlerin herhangi bir isteğe bağlı işlevi olabilir.


% 100 net değil, ama nereye gittiğini görmek için yeterli. Bunu, verilen bir dosyada 'hayvan' kodu olarak görebiliyordum. Ayrıca dallanma / şartlar üzerindeki kısım da iyidir. Bunu if / else yerine alternatif olarak düşünmemiştim.
ski

11

Bu doğrudan bir cevap değil, işlevsel bir dil uzmanı olmadığımdan% 100 kesin değil. Fakat her iki durumda da deneyimimi sizinle paylaşacağım ...

Bir yıl kadar önce seninle benzer bir teknedeydim. C ++ ve C # yaptım ve tüm tasarımlarım OOP'ta her zaman çok ağırdı. FP dilleri hakkında bir şeyler duydum, çevrimiçi olarak bazı bilgileri okudum, F # kitabını okudum, ancak bir FP dilinin OOP'un yerini nasıl alabileceğini ya da genel olarak yararlı olabileceğini hala anlamadım, çünkü gördüğüm çoğu örnek sadece çok basitti.

Benim için "atılım" pitonu öğrenmeye karar verdiğimde geldi. Python'u indirdim , sonra proje ana sayfasına gitmeye başladım ve birbiri ardına sorun yaşamaya başladım. Python mutlaka bir FP dili değildir ve içerisinde kesinlikle sınıflar oluşturabilirsiniz, ancak C ++ / Java / C # ile karşılaştırıldığında, çok daha fazla FP yapısı vardır, bu yüzden onunla oynamaya başladığımda, bilinçli bir karar vermedim. Kesinlikle mecbur kalmadığım sürece bir sınıf tanımla.

Python ile ilgili ilginç bulduğum şey, fonksiyon almanın ve onları daha karmaşık fonksiyonlar yaratmanın "dikilmesi" ne kadar kolay ve doğaldı ve sonunda probleminiz hala tek bir fonksiyonla çözüldü.

Kodlama sırasında tek sorumluluk ilkesi uygulamanız gerektiğine ve bunun kesinlikle doğru olduğuna dikkat çektiniz. Ancak, fonksiyon tek bir görevden sorumlu olduğu için, yalnızca mutlak en düşük seviyeyi yapabileceği anlamına gelmez. FP'de hala soyutlama seviyelerine sahipsiniz. Böylece, üst düzey işlevleriniz hala "bir" şey yapabilir, ancak bu "bir" şeyin nasıl elde edildiğinin daha ince detaylarını uygulamak için daha düşük seviyeli işlevlere devredebilir.

Ancak FP ile anahtar yan etkilerin olmamasıdır. Uygulamayı, tanımlanmış girişler ve çıkışlar seti ile basit bir veri dönüşümü olarak kabul ettiğiniz sürece, ihtiyacınız olanı elde edecek FP kodunu yazabilirsiniz. Açıkçası, her uygulama bu kalıba güzel bir şekilde uymayacak, ancak bir kez kullanmaya başladığınızda, ne kadar uygulamanın sığdığına şaşıracaksınız. Ve burası Python, F # veya Scala'nın parladığını düşündüğüm yer, çünkü size FP yapıları veriyorlar ancak durumunuzu hatırlamanız ve “yan etkileri ortaya koymanız” gerektiğinde, her zaman doğru ve denenmiş OOP tekniklerini geri alabilirsiniz.

O zamandan beri, bir grup python kodu, iç işleri için yardımcı programlar ve diğer yardımcı senaryolar olarak yazdım ve bazıları oldukça uzak bir şekilde ölçeklendi, ancak temel SOLID ilkelerini hatırlayarak, bu kodun çoğu hala sürdürülebilir ve esnek hale geldi. Tıpkı OOP'ta olduğu gibi, arayüzünüz de bir sınıftır ve sınıfları yeniden ayırdığınız ve / veya işlev eklediğiniz gibi hareket ettirirseniz, FP'de işlevlerle tamamen aynı şeyi yaparsınız.

Geçen hafta Java'da kodlamaya başladım ve o zamandan beri, neredeyse günlük olarak, OOP'de, işlevleri geçersiz kılan yöntemlerle sınıfları ilan ederek arayüzleri uygulamak zorunda olduğumu hatırlattığımı, bazı durumlarda Python'da aynı şeyi başarabileceğimi basit lambda ifadesi, örneğin, bir dizini taramak için yazdığım 20-30 satır kod, Python'da 1-2 satır ve sınıfsız olurdu.

FP kendileri daha yüksek seviyeli dillerdir. Python'da (özür dilerim, tek FP deneyimim) bir başka liste kavrayışının içinde bir başka liste kavrayışını bir araya getirip lambdalarla ve atılan diğer şeylerle bir araya getirebilirdim ve her şey sadece 3-4 kod satırı olurdu. C ++ 'da kesinlikle aynı şeyi başarabilirdim, ancak C ++ düşük seviyeli olduğu için 3-4 satırdan daha fazla kod yazmam gerekecek ve satır sayısı arttıkça SRP eğitimim başlayacak ve başlayacağım kodun nasıl küçük parçalara ayrılacağını düşünmek (yani daha fazla fonksiyon). Ancak sürdürülebilirliğin ve uygulama detaylarının gizlenmesiyle ilgili olarak, tüm bu işlevleri aynı sınıfa koyar ve onları özel yapardım. Ve işte orada ... Sadece bir sınıf yarattım, Python'da "return (.... lambda x: .. ....)" yazmış olurdum.


Evet doğrudan soruya cevap vermiyor, ama yine de harika bir cevap. python'da daha küçük scriptler veya paketler yazdığımda, her zaman ya da sınıfları kullanmıyorum. çoğu zaman sadece bir paket biçiminde olması mükemmel uyum sağlar. özellikle devlete ihtiyacım yoksa. Ayrıca liste kavramaların da çok faydalı olduğu konusunda hemfikirim. FP hakkında okuduğumdan beri, onların ne kadar güçlü olabileceğini anladım. bu da beni OOP'a kıyasla FP hakkında daha fazla şey öğrenmek istememe yol açtı.
Skift

Mükemmel cevap.
İşlevsel

Ve Ruby ... Tasarım felsefelerinden biri, tipik olarak isteğe bağlı olan bir argüman olarak bir kod bloğu alan yöntemlere odaklanıyor. Ve temiz sözdizimi düşünüldüğünde, bu şekilde düşünmek ve kodlamak kolaydır. C # 'da böyle düşünmek ve bestelemek zor. C # yazma fonksiyonel olarak ayrıntılı ve kafa karıştırıcı, direğe ayakkabılı hissediyor. Ruby'nin fonksiyonel C # düşünce kutumdaki potansiyelini görmek için işlevsel olarak daha kolay düşünmeye yardımcı olmasını seviyorum. Son analizde, işlevselliği ve OO’yu tamamlayıcı olarak görüyorum; Ruby'nin kesinlikle böyle düşündüğünü söyleyebilirim.
radarbob

8

Haskell'de en yakınınız "sınıf" dır. Bu sınıf , Java ve C ++'daki sınıflarla aynı olmasa da , bu durumda istedikleriniz için çalışacaktır.

Senin durumunda bu, kodunun nasıl görüneceği.

Sınıf Hayvan nerede 
say :: String -> ses 

Ardından, bu yöntemleri uyarlayan bireysel veri türlerine sahip olabilirsiniz.

örnek Hayvan Köpek nerede
s = "bark" deyin ++ s 

EDIT: - Köpek için uzmanlaşmadan önce, sisteme Dog'un hayvan olduğunu söylemeniz gerekir.

data Köpek = \ - burada bir şey - \ (Hayvan türetme)

EDIT: - Wilq için.
Şimdi bir deyimde foo işlevini kullanmak istiyorsanız, foo'nun sadece Animal ile çalışabileceğini söylemek zorunda kalacaksınız.

foo :: (Animal a) => a -> Dize -> Dize
foo a str = bir str söyle 

Şimdi köpekle foo çağırırsan havlar, kediyle çağırırsan miyavlar.

ana = yapmak 
Let d = dog (\ - cstr parametreleri - \)
    c = kedi  
şovda $ foo d "Merhaba Dünya"

Artık başka bir fonksiyon tanımının söyleyemeyeceğini söylüyorsunuz. Diyelim ki hayvan olmayan bir şeyle çağrılırsa derleme hatasına neden olur.


Bu işi tam olarak anlayabilmek için haskell konusunda biraz daha uğraşmak zorundayım, ama sanırım bundan vazgeçtim. Bunun daha karmaşık bir kod temeli ile nasıl hizalanacağına rağmen hala merak ediyorum.
1912'de

nitpick Hayvan harfle olmalıdır
Daniel Gratzer

1
Say işlevi, yalnızca bir String alırsa, onu bir Köpek üzerinde çağırdığınızı nasıl biliyor? Ve sadece bazı yerleşik sınıflar için “türetmek” değil mi?
WilQu

6

İşlevsel diller, polimorfizmi sağlamak için 2 yapı kullanır:

  • Birinci dereceden fonksiyonlar
  • Jenerik

Bunlarla polimorfik kod oluşturmak, OOP'nin kalıtım ve sanal yöntemleri kullanma şeklinden tamamen farklıdır. Her ikisi de en sevdiğiniz OOP dilinde (C # gibi) mevcut olsa da, çoğu işlevsel dil (Haskell gibi) on bir taneye kadar çıkar. Genel olmayan bir fonksiyonun görülmesi nadirdir ve çoğu işlev parametre olarak işlevlere sahiptir.

Böyle açıklamak zor ve bu yeni yolu öğrenmek için çok zaman harcamanız gerekecek. Ancak bunu yapmak için, OOP'yi tamamen unutmanız gerekir, çünkü işlevsel dünyada bu şekilde çalışmaz.


2
OOP tamamen polimorfizm ile ilgilidir. OOP'nin verilerinize bağlı işlevlere sahip olduğunu düşünüyorsanız, OOP hakkında hiçbir şey bilmiyorsunuzdur.
Öforik

4
polimorfizm OOP'un sadece bir yönüdür ve OP'nin gerçekten sorduğu şey olmadığını düşünüyorum.
Doc Brown

2
Polimorfizm, OOP'nin anahtar yönüdür. Bunu desteklemek için her şey var. Kalıtım / sanal yöntemler olmadan OOP, prosedürel programlama ile neredeyse tamamen aynıdır.
Öforik

1
@ErikReppen Sık sık "bir arayüz uygula" gerekli değilse, OOP yapmazsınız. Ayrıca, Haskell'in da modülleri var.
Öforik

1
Her zaman bir arayüze ihtiyacınız yoktur. Ancak onlara ihtiyacınız olduğunda çok faydalıdırlar. IMO, OOP'un bir başka önemli parçası. Modüller Haskell'e gelince, kodlama söz konusu olduğunda, bunun muhtemelen işlevsel diller için OOP'ye en yakın olduğunu düşünüyorum. En azından şu ana kadar okuduklarımdan. Hala çok farklı olduklarını biliyorum.
ski

0

bu gerçekten ne yapmak istediğine bağlı.

Seçici ölçütlere göre davranışı organize etmenin bir yoluna ihtiyacınız varsa, örneğin işlev nesneleri olan bir sözlük (karma tablosu) kullanabilirsiniz. python'da satırları boyunca bir şeyler olabilir:

def bark(what):
    print "barks: {0}".format(what) 

def meow(what):
    print "meows: {0}".format(what)

def climb(how):
    print "climbs: {0}".format(how)

if __name__ == "__main__":
    animals = {'dog': {'say': bark},
               'cat': {'say': meow,
                       'climb': climb}}
    animals['dog']['say']("ruff")
    animals['cat']['say']("purr")
    animals['cat']['climb']("well")

Ancak, (a) köpek ya da kedinin 'örneği' olmadığını ve (b) nesnelerinizin 'türünü' takip etmek zorunda kalacağınızı unutmayın.

Örneğin gibi: pets = [['martin','dog','grrrh'], ['martha', 'cat', 'zzzz']]. o zaman gibi bir liste anlama yapabilirsin[animals[pet[1]]['say'](pet[2]) for pet in pets]


0

OO Dilleri, düşük seviyeli dillerin yerine, bazen doğrudan bir makineyle arayüz oluşturmak için kullanılabilir. C ++ Elbette, ama C # için bile adaptörler var. Her ne kadar mekanik parçaları kontrol etmek ve bellek üzerinde küçük bir kontrol yapmak için kod yazsalar en iyi şekilde mümkün olduğunca düşük seviyelere yakın tutulur. Ancak bu soru, İş Hattı, web uygulamaları, IOT, Web Servisleri ve kitlesel kullanılan uygulamaların çoğunluğu gibi mevcut Nesne Yönelimli yazılımlarla ilgili ise, o zaman ...

Varsa cevap

Okuyucular Servis Odaklı Mimari (SOA) ile çalışmayı deneyebilir. Bu, DDD, N Katmanlı, N Katmanlı, Altıgen, her neyse. Son 10 yılda 70’lerde ve 80’lerde açıklandığı gibi, "Geleneksel" OO’yu (Aktif Kayıtlı veya Zengin Modeller) etkin bir şekilde kullanan bir Büyük işletme uygulaması görmedim. (Bkz. Not 1)

Hata OP ile ilgili değil, ancak soruyla ilgili birkaç sorun var.

  1. Sağladığınız örnek Polimorfizmi göstermek için basitçe üretim kodu değildir. Bazen tam olarak bunun gibi örnekler tam anlamıyla alınır.

  2. FP ve SOA'da, Veriler Business Logic'ten ayrılır. Yani, Veri ve Mantık bir arada gitmiyor. Mantık Hizmetlere Giriyor ve Veri (Etki Alanı Modelleri) Polimorfik davranışa sahip değil (Bkz. Not 2).

  3. Hizmetler ve İşlevler Polimorfik olabilir. FP'da, işlevleri sık sık parametre yerine diğer işlevlere değer yerine geçirirsiniz. Aynısını, Callable veya Func gibi OO Languages'da yapabilirsiniz, ancak yaygın değildir (Not 3'e bakınız). FP ve SOA’da, Modelleriniz Polimorfik değil, yalnızca Servisleriniz / İşlevleriniz. (Bkz. Not 4)

  4. Bu örnekte kötü bir kodlama durumu var. Sadece kırmızı renkli "köpek havlamaları" dizisinden bahsetmiyorum. Ayrıca CatModel ve DogModel’lerin kendileri hakkında da konuşuyorum. Bir Koyun eklemek istediğinizde ne olur? Kodunuza girmeli ve yeni kod oluşturmalısınız? Niye ya? Üretim kodunda, özellikleri olan sadece bir AnimalModel görmeyi tercih ederim. En kötüsü, özellikleri ve kullanım özellikleri çok farklıysa, bir AmphibianModel ve FowlModel.

Geçerli bir "OO" dilinde görmeyi beklediğim şey bu:

public class Animal
{
    public int AnimalID { get; set; }
    public int LegCount { get; set; }
    public string Name { get; set; }
    public string WhatISay { get; set; }
}

public class AnimalService : IManageAnimals
{
    private IPersistAnimals _animalRepo;
    public AnimalService(IPersistAnimals animalRepo) { _animalRepo = animalRepo; }

    public List<Animal> GetAnimals() => _animalRepo.GetAnimals();

    public string WhatDoISay(Animal animal)
    {
        if (!string.IsNullOrWhiteSpace(animal.WhatISay))
            return animal.WhatISay;

        return _animalRepo.GetAnimalNoise(animal.AnimalID);
    }
}

Temel akış

OO'daki Sınıflardan Fonksiyonel Programlamaya Nasıl Geçersiniz? Diğerlerinin dediği gibi; Yapabilirsin ama gerçekten değilsin. Yukarıdakilerin amacı, Java ve C # yaparken Sınıfları (dünyanın geleneksel anlamında) kullanmamanız gerektiğini göstermektir. Servis Odaklı bir Mimaride (DDD, Katmanlı, Katmanlı, Altıgen, her neyse) kod yazdığınızda, Verilerinizi (Etki Alanı Modelleri) Mantıksal İşlevlerinizden (Hizmetler) ayırdığınız için İşlevsel'e bir adım daha yakın olacaksınız.

OO Dili FP'ye bir adım daha yakın

Hatta biraz daha ileri götürüp SOA Servislerinizi iki türe ayırabilirsiniz.

İsteğe Bağlı Sınıf Tip 1 : Giriş Noktaları için Ortak Arayüz Uygulama Servisleri. Bunlar, "Pure" veya "Impure" başka işlevler oluşturabilen "saf" giriş noktaları olacaktır. Bu, RESTful bir API’dan Giriş Noktalarınız olabilir.

İsteğe Bağlı Sınıf Tip 2 : Saf İş Mantığı Servisleri. Bunlar "Saf" işlevselliğe sahip Statik Sınıflardır. FP'de "Saf" hiçbir yan etkisi olmadığı anlamına gelir. Açıkça Devlet veya Kalıcılık ayarını hiçbir yerde yapmaz. (Bkz. Not 5)

Bu nedenle, Servis Odaklı bir Mimaride kullanılan Nesneye Dayalı Dillerde Sınıflar'ı düşündüğünüzde, yalnızca OO Kodunuza fayda sağlamakla kalmaz, Fonksiyonel Programlamanın anlaşılması çok kolay görünmeye başlar.

notlar

Not 1 : Orijinal "Zengin" veya "Aktif Kayıt" Nesneye Yönelik Tasarım hala buralarda. İnsanlar bir on yıl veya daha uzun bir süre önce "doğru şekilde yapıyor" olduğunda, bunun gibi bir çok eski kural vardır. Bu tür bir kodun (doğru yapıldığında) son gördüğümde C ++ 'da Codebase adlı bir video oyunundan geliyordu. Burada hafızayı tam olarak kontrol ediyorlardı ve çok az yer kaplıyorlardı. FP ve Servis Odaklı Mimarilerin hayvanlar olmadığı ve donanım düşünmemeleri gerektiği söylenemez. Ancak, sürekli değişim, bakım, değişken veri boyutlarına ve öncelikli diğer özelliklere sahip olma yeteneğini yerleştiriyorlar. Video oyunlarında ve AI makinesinde, sinyalleri ve verileri çok hassas bir şekilde kontrol edersiniz.

Not 2 : Etki Alanı Modellerinde Polimorfik Davranış yok, Dış Bağımlılıklar da yok. Onlar "İzole" dir. Bu,% 100 Anemik olmaları gerektiği anlamına gelmez. Varsa inşaat ve değiştirilebilir mülk tadilatı ile ilgili birçok mantığı olabilir. Bkz. DDD "Değer Nesneleri" ve Varlıklar, Eric Evans ve Mark Seemann.

Not 3 : Linq ve Lambda çok yaygındır. Ancak bir kullanıcı yeni bir fonksiyon yarattığında, nadiren Func veya Callable'ı parametre olarak kullanır, FP'de ise bu modeli takip eden fonksiyonları olmayan bir uygulamayı görmek tuhaf olurdu.

Not 4 : Polimorfizmi Kalıtımla karıştırmamak. Bir CatModel, bir Hayvanın tipik olarak hangi Özelliklerine sahip olduğunu belirlemek için AnimalBase'i devralabilir. Ama gösterdiğim gibi, bunun gibi Modeller Kod Kokusu . Bu modeli görürseniz, onu parçalayıp verilere dönüştürmeyi düşünebilirsiniz.

Not 5 : Saf fonksiyonlar fonksiyonları parametre olarak kabul edebilir (ve yapabilir). Gelen işlev saf olmayabilir, ancak saf olabilir. Test amacıyla, her zaman saf olurdu. Fakat üretimde saf olarak kabul edilmesine rağmen, yan etkiler içerebilir. Bu, saf işlevin saf olduğu gerçeğini değiştirmez. Parametre fonksiyonu saf olmasa da. Kafa karıştırıcı değil! : D


-2

Böyle bir şey yapabilirsin ..

    function say($whostosay)
    {
        if($whostosay == 'cat')
        {
             return 'purr';
        }elseif($whostosay == 'dog'){
             return 'bark';
        }else{
             //do something with errors....
        }
     }

     function speak($whostosay)
     {
          return $whostosay .'\'s '.say($whostosay);
     }
     echo speak('cat');
     >>>cat's purr
     echo speak('dog');
     >>>dogs's bark

1
Olumsuz oy vermedim. Ancak benim tahminim, bu yaklaşımın ne işlevsel değil ne de nesne yönelimli olmasıdır.
Manoj R

1
Ancak iletilen konsept, işlevsel programlamada kullanılan örüntü eşleşmesine yakındır, yani $whostosayne yapılacağını belirleyen nesne türü haline gelir. Yukarıdakiler ek olarak başka bir parametreyi kabul edecek şekilde değiştirilebilir, $whattosayböylece onu destekleyen bir tür (örneğin 'human') onu kullanabilir.
syockit
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.