Kode sampel untuk menjelaskan masalah Banana Monkey Jungle oleh Joe Armstrong [ditutup]

14

Dalam buku Coders at work, Joe Armstrong menyatakan bahwa:

Saya pikir kurangnya usabilitas datang dalam bahasa berorientasi objek, bukan dalam bahasa fungsional. Karena masalah dengan bahasa berorientasi objek adalah mereka memiliki semua lingkungan implisit yang mereka bawa. Anda menginginkan pisang, tetapi yang Anda dapatkan adalah gorila yang memegang pisang dan seluruh hutan

Saya tidak mengerti di sini. Jika masalahnya adalah mendapatkan pisang, kita dapat merangkum semua logika di balik fungsi 'getBanana'. Bagaimana monyet dan hutan terlibat dalam konteks ini. Bisakah seseorang menulis potongan kode yang menjelaskan masalah dengan cara yang lebih mudah dimengerti, katakanlah, tunjukkan fakta bahwa Bananaobjek tersebut memerlukan objek Monkeydan Jungleuntuk diinisiasi, tolong?

Kha Nguyễn
sumber
Sayang sekali ini ditutup - itu menghasilkan beberapa diskusi yang baik. Lihatlah fungsi kelas satu sebagai starter.
Robbie Dee
1
@Euforia Diskusi jenis pertanyaan sebenarnya diperbolehkan tetapi pertanyaan mana yang subjektif bisa ... subjektif.
Robbie Dee
2
Saya percaya bahwa wawancara ini diadakan sebelum Joe Armstrong menulis tesis PhD-nya. Saat menulis tesis PhD-nya, Armstrong belajar tentang definisi sebenarnya dari OO, dan menyadari bahwa Erlang sebenarnya sepenuhnya berorientasi objek, pada kenyataannya, dari semua bahasa arus utama, Erlang mungkin adalah bahasa yang paling berorientasi objek! Dia tidak akan membuat pernyataan seperti itu jika dia tahu bahwa Erlang sebenarnya adalah bahasa OO. Apa yang dia bicarakan adalah otoritas sekitar , yang benar-benar tidak ada hubungannya dengan OO.
Jörg W Mittag
1
Hai, pertanyaan saya adalah tentang menyediakan beberapa kode sampel yang membantu saya (dan lainnya) memahami masalah dengan lebih baik. Cuplikan kode apa pun yang menunjukkan masalah dapat diterima, bukan hanya pendapat.
Kha Nguyễn

Jawaban:

16

Dia mengisyaratkan fakta, bahwa sebagian besar program OOP nyata tidak menghormati pemisahan kekhawatiran. Misalnya, Anda dapat memiliki kelas:

public class Banana
{
    public Monkey Owner {get;}
}

public class Monkey
{
    public Jungle Habitat {get;}
}

public class Jungle
{
}

Jika Anda menggunakan Banana, secara transitif perlu juga bergantung pada Monkeydan Jungle.

Tapi saya akan sangat tidak setuju bahwa ini masalah dengan OOP dan gaya fungsional itu entah bagaimana tidak memilikinya. Ini dapat dengan mudah diperbaiki di OOP dengan pengenalan abstraksi yang benar.

Masalahnya lebih tentang pengembang tidak peduli tentang pemisahan masalah. Dan saya tidak akan takut untuk menyatakan bahwa mayoritas programmer OOP adalah pemula, sementara programmer fungsional memiliki beberapa pengalaman, yang memotivasi mereka untuk memisahkan kode mereka dengan benar.

Kemungkinan abstraksi adalah:

public class Banana
{
    public IBananaOwner Owner {get;}
}

public interface IBananaOwner
{
}

public class Monkey : IBananaOwner
{
    public Jungle Habitat {get;}
}

public class Jungle
{
}

Dengan cara ini, Anda tahu bahwa Bananamemiliki pemilik, tetapi tidak harus demikian Monkey. Itu bisa apa saja. Dan itu membatasi apa yang dapat Bananadilakukan dengan pemilik hanya operasi yang ditentukan oleh IBananaOwner, yang menyederhanakan penalaran.

Euforia
sumber
Dan sebaliknya, bahasa fungsional mendukung fungsi-fungsi kelas satu di luar kotak - tidak berarti fungsi X dapat dikonsumsi dengan aman oleh fungsi Y tanpa efek samping.
Robbie Dee
Meskipun Anda membuat poin yang sangat baik, saya pikir Anda mungkin akan sedikit kesal di sini. Kutipan secara eksplisit menyebutkan lingkungan bukan bagaimana kode telah dirancang.
Robbie Dee
@RobbieDee Monkeydan Jungleadalah lingkungan untuk Banana. Dengan memperkenalkan abstraksi seperti IBananaOwner, lingkungan menjadi eksplisit. Dan bagaimana lingkungan ini dirancang adalah apa masalahnya.
Euforia
Anda mungkin benar tetapi saya tidak dapat membantu tetapi berpikir telah membaca ini antara lain bahwa gajah di ruangan (untuk menambah hewan lain) adalah bahwa masalahnya adalah komposisi yang benar dari fungsi-fungsi yang pemrograman fungsional, secara historis, memiliki meminjamkan diri untuk lebih.
Robbie Dee
@RobbieDee Anda tidak dapat mengganti apa yang saya tulis dengan komposisi fungsi sederhana. Setidaknya tidak di luar masalah contoh mainan. Dalam praktiknya, untuk sepenuhnya menggantikan desain OOP, hal-hal seperti generik kompleks, kelas tipe, monad dan lainnya diperlukan. Dan itu hanya mengubah satu jenis kompleksitas untuk jenis lain.
Euforia
13

Gorila bukan monyet!

Terlepas dari itu, Anda menjawab pertanyaan Anda sendiri dengan " kami dapat merangkum semua logika di balik fungsi 'getBanana' ". Yang saya inginkan adalah pisang, tetapi untuk mendapatkannya saya perlu memanggil getBananabeberapa objek, misalnya instance Gorillakelas. Objek pisang itu kemudian kemungkinan berisi referensi ke gorila miliknya dan bahwa objek gorila pada gilirannya akan memiliki referensi ke hutan miliknya. Jadi saya minta pisang, tapi dibungkus di belakang itu adalah seluruh hutan.

Ini adalah contoh ekstrem dan tidak akan selalu seburuk itu. Tapi tidak jarang berakhir dengan sistem OO seperti ini. Jadi, untuk menguji getBananametode itu, saya perlu membuat instance, atau mengejek, seluruh hutan.

David Arno
sumber
1
Ini tidak menjawab pertanyaan karena tidak memiliki kode sampel ...
Robbie Dee