Bu OOning boshqa dasturlarida qanday dasturlashtiriladi?

boshqa bir paradigma foydasiga OOP ning pastga tomonidagi jiddiy maqola bilan o'qib chiqdim. Men juda ko'p xatolikni topa olmaydigan misolga kirdim.

Men muallifning argumentlariga ochiq bo'lishni istayman va ularning fikrlarini nazariy jihatdan tushunish mumkin bo'lsa-da, ayniqsa, masalan, masalan, FP tilida qanday amalga oshirilishini tasavvur qilishga urinib ko'rmoqdaman.

From: http://www.smashcompany.com/technology/object-oriented-programming-is-an-expensive-disaster-which-must-end

// Consider the case where “SimpleProductManager” is a child of
// “ProductManager”:

public class SimpleProductManager implements ProductManager {
    private List products;

    public List getProducts() {
        return products;
    }

    public void increasePrice(int percentage) {
        if (products != null) {
            for (Product product : products) {
                double newPrice = product.getPrice().doubleValue() *
                (100 + percentage)/100;
                product.setPrice(newPrice);
            }
        }
    }

    public void setProducts(List products) {
        this.products = products;
    }
}

// There are 3 behaviors here:

getProducts()

increasePrice()

setProducts()

// Is there any rational reason why these 3 behaviors should be linked to
// the fact that in my data hierarchy I want “SimpleProductManager” to be
// a child of “ProductManager”? I can not think of any. I do not want the
// behavior of my code linked together with my definition of my data-type
// hierarchy, and yet in OOP I have no choice: all methods must go inside
// of a class, and the class declaration is also where I declare my
// data-type hierarchy:

public class SimpleProductManager implements ProductManager

// This is a disaster.

"Ushbu 3 ta xatti-harakat ma'lumotlarning ierarxikligi bilan bog'lanishi kerak bo'lgan biron-bir aql-idrok sababi bormi?" Deb yozgan shikoyatlariga qarshi yoki qarshi chiqishni istamasligimni unutmang.

Ayniqsa, so'ragan narsa, qanday qilib ushbu namunani FP tilida modellashtirilishi/dasturlashtirilishi mumkin (haqiqiy kod emas, nazariy)?

11
Maqolaning o'sha qismiga o'nta jumlani oldim. U parda ortidagi odamga e'tibor bermang. Boshqa tomondan, Haqiqiy Skotsmenlar asosan OOP dasturchilari bo'lganini bilmasdim.
qo'shib qo'ydi muallif sgwill, manba
Bir marta OOP ortiqcha ish haqi qo'shilmaydi. Ko'p oddiy oddiy funktsiyalar sinflardan hech qanday foyda ko'rmaydi. Qiymati kichik (agar til ularni statik sifatida amalga oshirishga ruxsat beradi deb hisoblasa) va katta miqdordagi nom-nashrlarni tashkiliy imtiyozlar beradi. (Misol uchun, C# matematika klassi.)
qo'shib qo'ydi muallif Sander Rijken, manba
Yaxshi OO yondashuvi narxlash siyosatini moslamalari sifatida modellashdir. Siyosat element bilan muhitda bir narx bilan bog'lanadi. Misol uchun, "kir yuvish mashinalarining asosiy narxlari $ 1000" siyosatdir. "Chorshanba kunlari 10% chegirma narxlari" - bu siyosat. "Ikkala siyosatni birlashtir" siyosati. "Bugun chorshanba" - bu muhit. Va hokazo. Berilgan ierarxiyaning "menejer" sufikasi tufayli yomon loyiha ekanligini bilamiz; siz buni ko'rganingizdan so'ng, siz ierarxik dizayndan keladigan yomon hidli hid mavjudligiga ishonchingiz komil bo'lishi mumkin.
qo'shib qo'ydi muallif CodeCharming, manba
OOP - boshdan oxirigacha dizaynerlik misstepsining fojiasi ekanligi shubhasizdir, va men uning bir qismi bo'lishdan faxrlanaman! - bu maqola o'qib bo'lmaydigan va siz misol qilib asosan noto'g'ri mo'ljallangan sinfi ierarxiyasining yomon ishlab chiqilganligi haqidagi dalillarni keltirib chiqaradi.
qo'shib qo'ydi muallif CodeCharming, manba
qo'shib qo'ydi muallif Jan Tomka, manba
Maqolada yozilish muallifi "No True Scotsman" misolining o'zi "Somon odam" argumenti ekanligi menga ma'lum bo'ldi.
qo'shib qo'ydi muallif user4127, manba
Nima uchun products null mumkin? Mening tajribamda null mumkin bo'lmagan to'plamlar foydali, ayniqsa, ularni bo'sh deb hisoblaganingizda.
qo'shib qo'ydi muallif user8669, manba
Kodning namunasida ushbu izohlarni o'qib chiqsam, boshimdan eshitgan barcha narsalar "Awww, mujuunnndaaaays holatiga o'xshaydi". ;)
qo'shib qo'ydi muallif FrustratedWithFormsDesigner, manba
OO dasturlari haqida hech narsa yo'q, bu 3 usulning bir xil sinfda to'planishini talab qiladi; xuddi shunga o'xshash xatti-harakatlar ma'lumotlari bilan bir xil sinfda bo'lishi shart bo'lgan OO dasturlari haqida hech narsa yo'q. Boshqacha aytganda, OO dasturlash bilan ma'lumotni xatti-harakatlarning bir xil klassiga qo'yishingiz mumkin yoki uni alohida shaxs/modelga bo'lishingiz mumkin. Har ikkala usulda ham, ma'lumotlarning ob'ektga qanday aloqasi borligi haqida hech narsa aytilmaydi, chunki ob'ekt kontseptsiyasi mantiqiy ravishda bog'liq usullarni guruhlash orqali asosan xatti- sinfga.
qo'shib qo'ydi muallif Ben Cottrell, manba
@EricKing Men hech qachon ushbu maqolani ijobiy bo'lmagan hollarda (bu holda, yaxshi yozilgan) ob'ektiv qoidalar mavjud bo'lmagan hollarda, "No True Scotsman" ning noto'g'ri e'tirofi bu kunlarda noto'g'ri e'tirof etilganligi sababli, ob'ektga yo'naltirilgan dasturlar). Ha, to'g'ri, bu haqiqiy emas, haqiqiy chiziqcha emas.
qo'shib qo'ydi muallif Jules, manba
Shuni esda tutingki, men birebir xaritalashni qidirmayman, yoki paradigmalarni taqqoslangan misol bilan taqqoslayman. Men ushbu misolni qanday (yarmini) teng bajarish mumkinligini bilmoqchiman? (masalan, "bu sinflarni aniqlab olishning hojati yo'q" degan so'zlar bilan bir joyda bo'lishi kerakligini taxmin qilar ekanmiz, biz bu vazifalarni shunday yo'lga qo'yishimiz mumkin edi, va biz bu usullarni keyingi holatlarda qo'llay olamiz, b, c)
qo'shib qo'ydi muallif rayrayrayraydog, manba
2014 yildan bu maqola bormi?
qo'shib qo'ydi muallif Ewan, manba
Bunday dasturlarning paradigmalarini taqqoslash mumkin emas. Bu erda har bir kishi, o'zlarining afzal ko'rgan paradigmasini dam olishdan ko'ra yaxshiroq ko'rsatishga qodir bo'lgan kod talablari bilan chiqishi mumkin, ayniqsa, boshqalarni noto'g'ri qo'llayotgan bo'lsa. Faqat haqiqiy, katta, o'zgaruvchan loyihangiz bo'lsa, siz turli xil paradigmalarning kuchli va zaif tomonlarini tushunishingiz mumkin.
qo'shib qo'ydi muallif Euphoric, manba
Kechirasiz, siz tushunmaysiz. Sizning namunangizda faqat bitta usul mavjud. Hech qanday murakkab xatti-harakatlar yo'q, qat'iylik yo'q, modelni qanday ishlatish kerakligi haqida hech narsa yo'q. Hech narsa. Nada. Bu kod misoli bilan hech narsani solishtirishning oqilona usuli yo'q.
qo'shib qo'ydi muallif Euphoric, manba
Birovning tilida protsessual kodni yozadigan odamdan yana bir rozet, keyin nima uchun OO ishlamayotganligi mo''jizaviy.
qo'shib qo'ydi muallif TheCatWhisperer, manba

6 javoblar

FP stilida Product o'zgaruvchan sinf bo'lib, product.setPrice bir Product ob'ektini mutatsiya qilmaydi, ammo uning o'rniga yangi ob'ektni qaytaradi va increasePrice funksiyasi "mustaqil" funktsiyadir. O'zingiz kabi o'xshash sintaksikni ishlatish (C #/Java kabi), mos keladigan funksiya shunday bo'lishi mumkin:

 public List increasePrice(List products, int percentage) {
    if (products != null) {
        return products.Select(product => {
                double newPrice = product.getPrice().doubleValue() *
                    (100 + percentage)/100;
                return product.setPrice(newPrice);     
               });
    }
    else return null;
}

Ko'rib turganingizdek, yadro bu erda haqiqiy emas, faqat OOP misolidan "boilerplate" kodi chiqarib tashlanadi. Biroq, buni OOP ning shaffof kodga olib kelishi haqidagi dalil sifatida ko'rmayapman, faqatgina etarlicha sun'iy ravishda kodli misolni yaratadigan bo'lsak, biror narsani isbotlash mumkin.

42
qo'shib qo'ydi
Tasavvur qilib, kollektsiyani nolishdan nafratlanish o'rniga nol bo'lishi mumkinligini aytmoqchiman. Mahalliy nusxalar/kollektsiyali qo'llab-quvvatlovchi funktsional tillar shu tarzda ishlaydi. OOP da qaytarib olishni xohlamayman. null ./rant tugadi
qo'shib qo'ydi muallif tim_yates, manba
@Mark FP va OO bir-birlarini istisno qilmaydi.
qo'shib qo'ydi muallif xirt, manba
@Mark: Albatta, va menimcha, OP buni allaqachon biladi. Men savolni "qanday qilib funktsional tarzda ifodalash kerak" deb tushunaman, OOP bo'lmagan tilda majburiy emas.
qo'shib qo'ydi muallif Peter LeFanu Lumsdaine, manba
Lekin, bu OOP tillarida Java yoki C# kabi foydali sinfda bo'lgani kabi statik usul bo'lishi mumkin. Ushbu kod qisman qisqartiradi, chunki siz ro'yxatga o'tishni talab qilasiz va uni o'zingiz ushlamang. Asl kod, shuningdek, ma'lumotlar strukturasini tutadi va faqat uni ko'chirib, tushunchalardagi o'zgarishsiz original kodni qisqartiradi.
qo'shib qo'ydi muallif JP., manba
Ushbu "ko'proq FP" ni bajarish usullari: 1) "qisqacha funksiyalar" o'rniga umumiy funktsiyalarni yozishni osonlashtiradigan va yuqori darajadagi yordamchi funktsiyalardan foydalanish uchun "if (x! = Null) mantiq. 2) linzalarni mahsulotning narxi bo'yicha linzalarning kontekstida foizlarni oshirishni qo'llash bo'yicha yagona mahsulot uchun narxni aniqlash uchun foydalaning. 3) Xarita uchun aniq lambdani yo'q qilish/Chaqiruvni tanlang.
qo'shib qo'ydi muallif Jack, manba
So'nggi jumla uchun +1. Odamlar generalizatsiya va generaldan istisnolar haqida mulohaza yuritishda yomondir.
qo'shib qo'ydi muallif CrazyLunatic, manba

Men so'radim, bu misol qanday qilib FP tilida modellashtiriladi/dasturlashtiriladi? (Nazariy kod emas, balki haqiqiy kod)?

"A" FP tilida? Agar etarli bo'lsa, men Emacs lispni tanlayman. U turlari turlari (turlari, turlari) mavjud, lekin ular faqatgina o'rnatilgan. Shunday qilib, sizning namunangiz "har bir narsani ro'yxatdagi narsalar bilan qanday qilib ko'paytirasiz va yangi ro'yxatni qanday qilib qaytarasiz?" Ga qisqartiradi.

(mapcar (lambda (x) (* x 2)) '(1 2 3))

Siz u erga borasiz. Boshqa tillar ham shunga o'xshash bo'ladi, farq siz odatiy funktsional "taalukli" semantika bilan ochiq turdagi foyda olasiz. Haskellni tekshiring:

incPrice :: (Num) -> [Num] -> [Num]  
incPrice _ [] = []  
incPrice percentage (x:xs) = x*percentage : incPrice percentage xs  

(Yoki shunga o'xshash narsa, yosh edi ...)

Muallifning argumentlariga ochiq bo'lishni istayman,

Nima uchun? Men maqolani o'qishga harakat qilardim; Men sahifadan keyin bo'shashib qolganimdan keyin tezroq skanerladim.

Maqolaning muammosi OOPga qarshi emas. Men ham ko'r-ko'rona "OOP" ga qarshi emasman. Mantiqiy, funktsional va OOP paradigmalariga asosan, iloji boricha tez-tez bir xil tilda dasturlashtirilgan va tez-tez uchta, mutlaqo majburiy yoki hatto assembler darajasida dasturlashtirilgan. Men hech qachon hech qachon deyman, bu paradigmalarning har biri har jihatdan boshqasiga muttasil supuridir. tilni yaxshi ko'raman deb da'vo qilamanmi? X X yaxshiroqmi? Albatta xohlayman! Biroq, bu maqola haqida emas.

Maqolaning muammoni shundan iboratki, u birinchi va oxirgi jumlaga qadar ko'plab ritorika vositalaridan foydalanadi. Hatto o'z ichiga olgan barcha xatolarni ta'riflashga ham umuman befoyda. Muallif, muzokara jarayonida nolinchi qiziqish borligini juda yaxshi biladi, u salibchilikda. Xo'sh, nima uchun bezovtalanasiz?

Kun oxirida bularning barchasi ishni bajarish uchun faqat vositadir. OOP yaxshiroq bo'lgan ish joylari bo'lishi mumkin va FP yaxshiroq bo'lgan boshqa joylar ham bo'lishi mumkin, yoki ikkalasi ham ustunlikka ega. Muhimi, ish uchun to'g'ri vositani tanlash va uni bajarish.

17
qo'shib qo'ydi
Haskell kodingizda Num cheklovi kerak emasmi? Aks holda qanday qilib qo'ng'iroq qilish mumkin (*)?
qo'shib qo'ydi muallif kraftydevil, manba
"U suhbatda nolinchi qiziqish borligini juda aniq, u salibchilikda".
qo'shib qo'ydi muallif Euphoric, manba
@ jk, men Haskellni qilganim asrlar mobaynida, u faqat u izlayotgan javob uchun OPning cheklanishini qondirish edi. ;) Agar kimdir mening kodimni tuzatmoqchi bo'lsa, o'zingizni erkin his qilasiz. Lekin, albatta, men uni raqamga almashtiraman.
qo'shib qo'ydi muallif AnoE, manba

Muallif juda yaxshi fikrga ega bo'lib, uni qo'llab-quvvatlashga harakat qilish uchun mutlaqo namunali tanladi. Shikoyat sinfni amalga oshirish bilan bog'liq emas, chunki ma'lumotlar hiyerarşisinin funktsiya hiyerarşisi bilan bir-biriga bog'liq emasligi.

Shundan keyin muallifning fikrini tushunish uchun u faqat bitta sinfni funktsional uslubda qanday amalga oshirishini ko'rishga yordam bermaydi. Ushbu sinfning atrofidagi funktsional uslubdagi ma'lumotlar va funktsiyalarni butun kontekstida qanday tasarlayacağını ko'rishingiz kerak.

Mahsulotlar va narxlashning mumkin bo'lgan ma'lumotlar turlarini o'ylab ko'ring. Bir nechta miya bo'roni: nom, yuk kodi, toifasi, yuk og'irligi, narx, valyuta, chegirma kodi, chegirmali qoida.

Ob'ektga yo'naltirilgan dizaynning oson qismi. Yuqoridagi "ob'ektlar" uchun biz faqatgina sinf yaratmoqdamiz va biz yaxshi, to'g'rimi? Ulardan bir nechasini birlashtiradigan Product sinfini yaratish kerakmi?

But wait, you can have collections and aggregates of some of those types: Set[category], (discount code -> price), (quantity -> discount amount), and so forth. Where do those fit in? Do we create a separate CategoryManager to keep track of all the different kinds of categories, or does that responsibility belong to the Category class we already created?

Endi siz ikkita toifadagi narsalaringizning ma'lum miqdoriga ega bo'lsangiz, sizga narxlari tushiradigan funksiyalar haqida nima deyish mumkin? Bu Product sinfida, Category sinfida, DiscountRule sinfida, CategoryManager yangi narsaga muhtojmiz? DiscountRuleProductCategoryFactoryBuilder kabi narsalar bilan shug'ullanamiz.

Funktsional kodda sizning ma'lumotlaringiz ierarxiyasi sizning funktsiyalaringiz uchun mutlaqo diktatura hisoblanadi. Funktsiyalaringizni semantik ma'noda qanday qilib o'zgartirishi mumkin. Misol uchun, mahsulot bahosini o'zgartiradigan barcha funktsiyalarni guruhlashingiz mumkin, bu holda quyidagi Scala misolida mapPrices kabi umumiy funktsiyalarni omillashtirish mantiqan bo'ladi:

def mapPrices(f: Int => Int)(products: Traversable[Product]): Traversable[Product] =
  products map {x => x.copy(price = f(x.price))}

def increasePrice(percentage: Int)(price: Int): Int =
  price * (percentage + 100)/100

mapPrices(increasePrice(25))(products)

Bu erda decreasePrice , applyBulkDiscount va hokazo. Kabi narxlarga bog'liq bo'lgan boshqa funksiyalarni kiritishim mumkin.

Bundan tashqari biz Products to'plamini ishlatamiz, OOP versiyasi ushbu to'plamni boshqarish usullarini o'z ichiga olishi kerak, lekin siz ushbu modulni mahsulot tanlovi haqida bo'lishini xohlamasligingiz uchun narx haqida bo'lishni xohlar edingiz. Funktsional ma'lumotlar birikmasi sizni o'sha erda to'plash uchun boshqaruvni olib tashlashga majbur qildi.

Buni products a'zolarini alohida sinfga qo'yish orqali hal qilishga urinib ko'rishingiz mumkin, lekin keyin siz juda qattiq bog'langan sinflar bilan yakunlanasiz. OO dasturchilari funktsional ma'lumotlar birikmasini juda tabiiy va foydaliroq deb hisoblaydilar, ammo moslashuvchanlikni yo'qotish bilan bog'liq bo'lgan yuqori xarajat mavjud. Funktsiyani yaratgandan so'ng, uni bitta va birgina sinfga belgilashingiz kerak. Funktsiyani ishlatmoqchi bo'lgan har qanday vaqtda, o'zingizning bog'langan ma'lumotlardan foydalanish nuqtasiga ulanishning yo'lini topishingiz kerak. Bu cheklovlar juda katta.

6
qo'shib qo'ydi

Ma'lumotlar va funktsiyalarni muallifdan ajratish uchun faqatgina F # ("FP tili") da shunga o'xshash bo'lishi mumkin.

module Product =

    type Product = {
        Price : decimal
        ...//other properties not mentioned
    }

    let increasePrice ( percentage : int ) ( product : Product ) : Product =
        let newPrice = ...//calculate

        { product with Price = newPrice }

Mahsulotlar ro'yxatida bu tarzda narx oshishi mumkin.

let percentage = 10
let products : Product list = ... //load?

products
|> List.map (Product.increasePrice percentage)

Eslatma: FP bilan tanish bo'lmagan bo'lsangiz, har funktsiya qiymatni qaytaradi. C kabi tildan kelib chiqadigan bo'lsak, oldingi return oldida bo'lgani kabi, oxirgi funksiyani funksiyada ko'rib chiqishingiz mumkin.

Men ba'zi bir qo'shimcha izohlarni kiritdim, lekin ular keraksiz bo'lishi kerak. Getter/setter bu erda keraksiz, chunki modul ma'lumotlarga ega emas. Ma'lumotlar strukturasi va mavjud operatsiyalarga egadir. Bu List bilan ham ko'rish mumkin, bu esa xarita </​​code> ro'yxatidagi har bir elementda funktsiyani ishlatish uchun paydo bo'ladi va natijani yangi ro'yxatga qaytaradi.

Mahsulot modulida pastadir haqida biror narsa bilish kerak emasligiga e'tibor bering, chunki u javobgarlik ro'yxat moduli (loopga bo'lgan ehtiyojni yaratgan) bilan qoladi.

2
qo'shib qo'ydi

Men buni funksional dasturlash bo'yicha mutaxassisi emasman, deb boshlayman. Men OOPga ko'proq odamman. Shunday qilib, quyida men FP bilan bir xil funktsional imkoniyatlarni qanday qilib amalga oshirayotganingizdan amin ekanman, noto'g'ri bo'lar edim.

Bu "Typecript" (shuning uchun barcha turdagi izohlar). Turi (javascript kabi) ko'p tilli tildir.

export class Product extends Object {
    name: string;
    price: number;
    category: string;
}

products: Product[] = [
    new Product( { name: "Tablet", "price": 20.99, category: 'Electronics' } ),
    new Product( { name: "Phone", "price": 500.00, category: 'Electronics' } ),
    new Product( { name: "Car", "price": 13500.00, category: 'Auto' } )
];

// find all electronics and double their price
let newProducts = products
    .filter( ( product: Product ) => product.category === 'Electronics' )
    .map( ( product: Product ) => {
        product.price *= 2;
        return product;
    } );

console.log( newProducts );

Batafsil (va yana bir FP mutaxassisi emas), tushunish kerak bo'lgan narsa oldindan aniqlangan xatti-harakatlarning ko'p emasligi. Albatta, bu butun ro'yxat bo'yicha narxni oshirishni qo'llaydigan "o'sish bahosi" usuli yo'q, chunki bu OOP emas: bunday xatti-harakatni aniqlash uchun hech qanday sinf yo'q. Mahsulotlar ro'yxatini saqlaydigan ob'ektni yaratish o'rniga, siz mahsulot qatorini yaratasiz. Keyinchalik, ushbu qatorni o'zingiz xohlagan tarzda o'zgartirish uchun standart FP protsedurasidan foydalanishingiz mumkin: ayrim narsalarni tanlash uchun filtri, ichki jadvalni sozlash uchun xaritalar va boshqalar....... API SimpleProductManager sizga beradi. Ba'zilar buni afzal ko'rishi mumkin. Bundan tashqari, ProductManager sinfi bilan bog'liq har qanday yuk haqida xavotirlanmasangiz ham to'g'ri. Nihoyat, "SetProducts" yoki "GetProducts" haqida hech qanday tashvish yo'q, chunki mahsulotingizni yashiradigan hech qanday ob'ekt yo'q: buning o'rniga, siz faqat siz bilan ishlayotgan mahsulotlar ro'yxatiga egasiz. Shunga qaramay, bu siz bilan gaplashadigan vaziyatlarga/shaxsga qarab afzallik yoki kamchilik bo'lishi mumkin. Bundan tashqari, hech qanday sinf hiyerarşisi (u shikoyat qilgan narsa) aniq, chunki hech qanday sinflar yo'q.

Men uning barcha rantlarini o'qish uchun vaqt topmadim. FP amaliyotidan foydalanganda men qo'llayman, lekin men, albatta, ko'proq OOP turidagi odamman. Men sizning savolingizga javob berganimdan keyin, men uning fikrlari haqida qisqacha sharh beraman deb o'yladim. O'ylaymanki, bu OOPning "inqirozi" ni ta'kidlaydigan juda ajoyib misol. Ushbu muayyan holatda ko'rsatilgan funktsionallik uchun, OOP ehtimol o'ta qotib qoladi va FP ehtimol yanada yaxshiroq bo'ladi. So'ngra, yana bir bor, agar siz xarid qilish vositasi kabi narsalar bo'lsa, mahsulot ro'yxatini himoya qilsangiz va unga kirishni cheklab qo'ysangiz (menimcha) dasturning juda muhim maqsadidir va FP bu kabi narsalarni amalga oshirish uchun hech qanday yo'l yo'q. Shunga qaramay, men faqat FP mutaxassisi emasman, ammo elektron tijorat tizimlari uchun xarid qilish vositalarini qo'llaganimdan, OOPni FPdan ko'ra ko'proq ishlatishim mumkin. OOPdagi inkapsulatsiya tamoyillari sizning narsalaringizni to'g'ri o'zgartirishga, har doim bir holatdan ikkinchisiga o'tishingizga va xarid qilish savatingiz har doim yangilanganligiga ishonch hosil qilish uchun sizga ko'proq nazorat beradi.

Shaxsan men "X faqat qo'rqinchli, har doim Y" uchun bunday kuchli argumentni keltiradigan har kimni jiddiy qabul qilaman. Dasturlash turli xil vositalar va paradigmalarga ega, chunki bu muammoni hal qilish uchun turli xil muammolar mavjud. FP o'z o'rnini egallaydi, OOP o'z o'rnini egallaydi va hech kim, agar bizning vositalarimizning kamchiliklarini va afzalliklarini tushunolmasa va ulardan foydalanganda hech kim buyuk dasturchi bo'lishni xohlamaydi.

** Izoh: Shubhasiz, mening misolimdagi bitta sinf mavjud: mahsulot sinf. Bu holatda u shunchaki soxta ma'lumotli konteyner bo'lsa-da, men undan foydalanishni FP tamoyillariga zid deb o'ylamayman. Bu tip tekshiruvi uchun yordamchi bo'ladi.

** Eslatma: Men boshimni yuqoridan eslamayapman va xarita funksiyasidan foydalanish usulini mahsulotni joyida o'zgartiradimi, yo'qmi, ya'ni men tasodifiy mahsulotning asl mahsulotidagi narxini ikki barobar ko'paytirdimmi? qator. Shubhasiz, bu FP ning oldini olishga harakat qiladigan yonma ta'siri va biroz ko'proq kod bilan men buni amalga oshmasligiga amin bo'lishim mumkin.

1
qo'shib qo'ydi
Bu mumtoz ma'noda OOP misoli emas. Haqiqiy OOPda ma'lumotlar xulq bilan birlashtiriladi; Bu erda siz ikkitani ajratdingiz. Bu, albatta, yomon narsa emas (aslida uni toza deb topaman), lekin bu klassik OOP deb atashim emas.
qo'shib qo'ydi muallif sgwill, manba

Menimcha, SimpleProductManager bolaligida (uzaytiriladi yoki meros bo'lib qoladi).

Asosan ob'ektni qanday harakatlar (xatti-harakatlar) ni belgilaydigan shartnoma bo'lgan ProductManager interfeysining to'g'ri amalga oshirilishi.

Agar u bolaligida (yoki yaxshiroq o'qigan bo'lsa, sinfni yoki sinfni boshqa sinf funktsional imkoniyatlarini kengaytirgan) shunday deb yoziladi:

class SimpleProductManager extends ProductManager {
    ...
}

Asosan, muallif shunday deydi:

Qaysi xatti-harakatlarning ba'zi ob'ektlari mavjud: setProducts, increasePrice, getProducts. Va biz ob'ektning boshqa xatti-harakatlari yoki xatti-harakatlar qanday amalga oshirilganligi haqida bizda hech narsa yo'q.

SimpleProductManager klassi uni bajaradi. Asosan, u amallarni bajaradi.

Uning asosiy xatti-harakatlari narxni bir necha foizli qiymatga oshirishdan iborat bo'lganligi sababli, PercentagePriceIncreaser deb atash mumkin.

Lekin biz boshqa sinfni ham qo'llay olamiz: ValuePriceIncreaser, o'z ta'siriga ega bo'ladi:

public void increasePrice(int number) {
    if (products != null) {
        for (Product product : products) {
            double newPrice = product.getPrice() + number;
            product.setPrice(newPrice);
        }
    }
}

Tashqi nuqtai nazardan, hech narsa o'zgargani yo'q, interfeys bir xil, hali ham uchta usul mavjud, biroq xatti-harakatlar boshqacha.

FPda interfeyslar kabi hech narsa yo'qligi sababli uni amalga oshirish qiyin bo'ladi. C da, misol uchun, biz ko'rsatgichlarni funksiyalarga moslashtira olamiz va ehtiyojlarimiz asosida mos ravishda qo'ng'iroq qilishimiz mumkin. Natijada OOP da juda o'xshash ishlaydi, lekin uning kompilyatori tomonidan "avtomatlashtirilgan".

0
qo'shib qo'ydi