The One Thing You Cannot Do in Object-Oriented Programming but You Can in Functional

preview_player
Показать описание
In Object-Oriented Programming, objects are instances of classes and they encapsulate behavior and state - that is what every textbook on OOP is teaching. However, there's a subtle limitation in OOP when it comes to dealing with changes in the state of these objects.
We often try to mitigate that limitation by applying the State design pattern, but that adds extra complexity and potential confusion to downstream components, especially when using Object-Relational Mappers (ORMs).
In this video, you will learn to recognize the fundamental limitation of Object-Oriented Programming and how Functional Programming (FP) offers an inverse perspective. Through immutability and transformations of values, FP tends to make state transitions explicit and predictable, leading to a more straightforward way of handling the issues that would otherwise be too large a burden for a corresponding object-oriented model.
This requires a shift in thinking and can introduce its own challenges and learning curves. It is a fascinating topic, shedding light on the fundamental underpinnings of OOP and FP, and their practical implications in software development.

Thank you so much for watching! Please like, comment & share this video as it helps me a ton!! Don't forget to subscribe to my channel for more amazing videos and make sure to hit the bell icon to never miss any updates.🔥❤️

⭐ Learn more from video courses:

▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
⭐ CONNECT WITH ME 📱👨

▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
👨 About Me 👨
Hi, I’m Zoran, I have more than 20 years of experience as a software developer, architect, team lead, and more. I have been programming in C# since its inception in the early 2000s. Since 2017 I have started publishing professional video courses at Pluralsight and Udemy and by this point, there are over 100 hours of the highest-quality videos you can watch on those platforms. On my YouTube channel, you can find shorter video forms focused on clarifying practical issues in coding, design, and architecture of .NET applications.❤️
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
⚡️RIGHT NOTICE:
The Copyright Laws of the United States recognize a “fair use” of copyrighted content. Section 107 of the U.S. Copyright Act states: “Notwithstanding the provisions of sections 106 and 106A, the fair use of a copyrighted work, including such use by reproduction in copies or phono records or by any other means specified by that section, for purposes such as criticism, comment, news reporting, teaching (including multiple copies for classroom use), scholarship, or research, is not an infringement of copyright." This video and our youtube channel, in general, may contain certain copyrighted works that were not specifically authorized to be used by the copyright holder(s), but which we believe in good faith are protected by federal law and the Fair use doctrine for one or more of the reasons noted above.

#csharp #objectorientedprogramming #functionalprogramming
Рекомендации по теме
Комментарии
Автор

I struggled with this issue with oop for many years but as i have learned a bit of accounting, it helped me crack the issue. If you think of invoice as an object, you feel that it has behaviour. But invoice is simply a record as you call it in functional programming. What does it record? It records the services provided or items sold or a combination of both (example your car mechanic invoice which includes labour charges and parts sold). The payment for an invoice is a separate record and needs to be tracked separately. You may be required at some point in the life of the app how the payment was done (cash, card, wire transfer etc). There may be partial payment or there may be payment of more than one invoice through single instrument like a bank cheque. The state of the invoice is two additional attributes, if it is paid and if yes on which date, come from a different data source and should not ideally map to same table. A transactional database and a reporting database are two different designs. So if you are checking only one of them. If you are checking paid status of the invoices, it's coming from reporting db and that's a read only data. The payment operation you do on the invoice goes to transactional db and it would at times take a while to reflect in reporting db. So this is not as simple problem to club all these concerns into one sample. Oop at times requires deeper thinking of the domain to solve the problem correctly.

hemant-sathe
Автор

How does this solve the ORM problem? I see the same issue here. The type has changed. The object needs to update.

LE
Автор

A function in a functional programming language is equivalent to a single method interface in object oriented programming. An object in object oriented programming is equivalent to a closure in functional programming. You don't really miss anything using one or the other paradigm, but ease of use will definitely be an important factor in choosing the paradigm to use. Applying SOLID principles in OOP makes your code more similar to functional code, that is small objects and small interfaces with small state and small number methods and with little or no subclasses.

kdakan
Автор

I haven't even heard of a record type in c#, I assumed you'd use structs for the functional approach. Time to do some more googling.

jamo
Автор

Can you please simply explain why a nullable PaidOn property in a single Invoice type would be bad? I think it's a perfect model of a real-world invoice. Real-world invoice can be stamped with a red colored paid on this date and the null state of PaidOn property would mean the real-world invoice doesn't have the red stamp on it yet. What's wrong with this simple model? Why complicate it with multiple types like UnpaidInvoice and PaidInvoice?

XtroTheArctic
Автор

You can change the paid function call type to just accept OutstandingInvoice it will put responsibility on the client to pattern match the invoice and call paid function

Endomorphism
Автор

But it also means that we don't need several classes to design the solution. We can have one Invoice class with a propery "PaymentStatus" - can be enum as well. Yes I know it is redudant with a PaidDate? but it also can give a clean info about the invoice. Also I would not rely on a system date about payment. Also we can introduce a new class Payment wich can have Invoice reference. So that class can be used for payments. Samo kažem.

Also let not mix ORM entities with domain objects.

dxs
Автор

How would you load an invoice from the database so it's the correct type? I assume it's all in one table "Invoices" of entity type Invoice, so how would you load a PaidInvoice or OutstandingInvoice?

CowCow-om
Автор

Awesome video (as always)! I credit you to my increasingly growing interest of applying Functional patterns in C# after I watched your PluralSight course.

Do you have example code that you could show a solution that is leveraging an ORM like EF for data persistence with the functional record types that accounts for the runtime type change? I'm trying to get my mind around the layer/plumbing needed to keep those to approaches in sync.

seankirk
Автор

Interesting! Although, I'm fairly sure that in 99% of cases, State patterns with OOP will not be used, but rather a pragmatic solution will be used. So in this case, the PaidOn? property will just be added to the base class to avoid the hassle. But it's an interesting approach nevertheless.

allinvanguard
Автор

FP solution still changes the reference. If you have a List<Invoice> for example, and you want to change the type of one of its elements, without actually changing the list, you can't, even with FP. At least not with this approach.

davidc
Автор

PaidOn looks like a prop that should be in any invoice. Or, you could have an property that indicates the status on every invocie. Do people exist who just have to create different types in such cases, instead of adding a few more props?

DavidSmith-efeh
Автор

whats your opinion on language-ext lib?

benqbenq
Автор

Development fundamental, ERD and DFD as a Starting point before coding, will reduce some of the complexities related OOP and domain knowledge required.

rotteneggconcept
Автор

is it a naïve solution to just add a property? or was the example just for illustrative purposes?

istovall
Автор

Interesting video but I might have missed something. The idea behind the State pattern is to decouple the class from its state. Therefore shouldn't you have Invoice and an associated InvoiceState? So what you specialize is the state, not the invoice: PaidState, OutstandingState, ... The behavior of the invoice will then change as its state changes, as if the invoice changed its class.

vincentjacquet
Автор

This definitely an issue I have come across many times. The question in my mind is when will the ORM (or other persistence helpers) catch up with the FP approach. Right now if you are using EF the simplest and pragmatic approach would be to have the Invoice table have a nullable PaidOn column and let your C# model represent it that way too. This is not great OOP let alone FP.

In general relation databases are themselves not great at representing an entity that has a life cycle. Only fields that should not be null at the beginning of that entities life can be declared not null. However, in reality the entity evolves and in other points of its life multiple fields can become mandatory (in fact the fact they are set at all indicates the entity's new "run time type" e..g a view on the invoice table where PaidOn IS NOT NULL becomes the PaidInvoice view).

codingbloke
Автор

Hi Zoran.
I really appreciate your videos. Thanks for taking the time to make them. I learned a lot from you.

I agree with you that FP has many advantages over OOP when building a solid state machine. But in my experience, a state machine based on types is hard to persistent using an ORM. You can of course use a NoSQL document database but that is not an option for us. Instead, we use a state property and define the set of valid state transitions. The setter of the state property checks that the transition is valid and throws an exception otherwise. I am aware that this is not nearly as solid as your FP suggestion but it works and it is simply to model the state property with an ORM.

How would you persist your record example with an ORM like NHibernate or Entity framework?

AndersBaumann
Автор

In Smalltalk, where the term object-oriented was coined, every object has a method "become" which allows an object to become any other object of any class. I don't like OOP but it is not true that in OOP objects cannot become other objects.

jboss
Автор

Thank you so much for another video.

If I understending correctly the branching with switch pattern is mainly for benefit of consumer, say, for this example a view model, who can now more elegantly render appropiate html base on the type from branching instead of mess of if and else or I am mixing it with discriminated unions which a bit diffrent topic?

secury