Immutable Design: Why You Should Care

  Рет қаралды 8,959

Zoran Horvat

Zoran Horvat

Күн бұрын

Пікірлер: 38
@zoran-horvat
@zoran-horvat 8 ай бұрын
Check out Dometrain and use code ZORAN for 15% off any course ► dometrain.com/?coupon_code=ZORAN Download source code ► www.patreon.com/zoranhorvat Join Discord server with topics on C# ► codinghelmet.com/go/discord Enroll course *Beginning Object-Oriented Programming with C#* ► codinghelmet.com/go/beginning-oop-with-csharp Subscribe ► kzbin.info/door/xsWfh8LCcn55mFB6zGBT1g
8 ай бұрын
Check if ArgumentException didn't get ThrowIf... methods to get 21% discount from me 😂
@1992jamo
@1992jamo 8 ай бұрын
Extremely interesting. I had never heard of System.Collections.Immutable and had previously wondered how on earth you'd keep record classes with mutable members. I need to retrain my brain to read primary constructors more fluently, because I am so used to seeing any member declared within the scope of the object. I know the usefulness of extension methods, but I typically avoid them if I have control of the base object because it hides behaviour and implementation. If you were reading the source of a large project, you might not know someone has extended it, and more often than not you'd assume they haven't if they can add the behaviour directly to the type. The value of your videos never ceases and every time I learn something new. One more tool in the belt! I've popped you a fiver on patron and joined your discord. I'd love to give more considering how much I have learned, but I'm not in the position to right now.
@zoran-horvat
@zoran-horvat 8 ай бұрын
Thanks! Your observations about extension methods are sound. The prerequisite for proper use of extension methods is that the type exposes its components publicly. When they start from the type, they begin to make sense. Attaching extension methods to an unsuspecting type usually looks like a hack.
@David-id6jw
@David-id6jw 8 ай бұрын
@@zoran-horvat Out of curiosity, do you have any thoughts on how the upcoming extension types might affect how you approach building functional types?
@zoran-horvat
@zoran-horvat 8 ай бұрын
@@David-id6jw Extension types look more object-oriented to me, with a caveat: you cannot extend a type which is not ready for it, primarily in that it exposes its components publicly. Doing so already requires immutability of components and then functional design is already at the arm's length. Therefore, it is all tightly connected. I personally like extension properties a lot.
@WalderFrey
@WalderFrey 8 ай бұрын
How do you ensure that all consumers use a factory function at the 7:17 mark? Can't you keep on using the constructor, e.g. new Title("C# for Dummies")? I think I'm missing something here 🙂.
@zoran-horvat
@zoran-horvat 8 ай бұрын
Code review and automated analyzers (a.k.a. fitness functions). The compiler cannot save the team from a member who doesn't follow the coding rules.
@eduardpopescu9109
@eduardpopescu9109 8 ай бұрын
You can have an explicit constructor and make it private, if you wish. You don't have to use the primary constructor if it doesn't help you. By not exposing the constructor, you force the consumers to use the factory method. Keep in mind that records are still classes, unlike record structs.
@zoran-horvat
@zoran-horvat 8 ай бұрын
@@eduardpopescu9109 That defies the purpose of records. I don't agree that programmers should write additional code to fight against the syntax and the teammates they don't trust. Write one fitness function for the entire project instead and use the language as it is.
@chris-pee
@chris-pee 8 ай бұрын
@@zoran-horvat Interesting. Could you link any resource about creating such an analyzer? I know about libraries such as ArchUnitNET but I'm not sure how you'd go about that in this case.
@robinheyer708
@robinheyer708 7 ай бұрын
8:18 Hah! Love the humour! I hope to one day encounter a ThisIsSoSmart() method in a codebase out in the wild. Or better yet, write one myself! I've been trying F# the last few Saturdays and I'm surprised how easy to pick up the writing style is. I really only use var in C# when I'm constructing some elaborate Linq chain but using the type inference in F# feels very natural. And back in C# I still avoid var as much as I used to. I've only done a few Exercism exercises so far but I'm enjoying the emphasis on pattern matching and using discriminated unions. I have had the occasional OOP brain block (where I'll curse at those same things I just mentioned I'm enjoying) but it hasn't been that bad. It has made me consider using extension methods more to write more expressive and concise code. Trying a custom Result Option implementation for low impact error handling which I believe you have also covered in a video. Maybe I'll write a class library with a Book type in F# and see how much of the refactoring you demonstrated here would still be needed if I used that in C#.
@zoran-horvat
@zoran-horvat 7 ай бұрын
F# would sever the noise I have in my C# code and make it even shorter.
@osmantas369
@osmantas369 8 ай бұрын
Great and funny to hear rhyme like "immutable mutables mutates mutable immutables" lol
@ElOroDelTigre
@ElOroDelTigre 8 ай бұрын
Amazing as always. Thanks, Zoran.
@brendonanderson8673
@brendonanderson8673 5 ай бұрын
Supporting on Patreon! Thanks for these videos💪
@zoran-horvat
@zoran-horvat 5 ай бұрын
@@brendonanderson8673 Thanks!
@leos-clockworks335
@leos-clockworks335 8 ай бұрын
I am slowly moving into a more Immutable design, where possible, and your videos are very helpful, so thanks! I was wondering what are your thoughts on having a validation record for specific use cases (Similar to 'Title' in this video and also shown in a different video of yours.). For example, having a record for a non-negative number, non-empty string etc. and of course project specific records. On one hand, it seems useful, to skip that pesky validation, as some places there are so many checks whenever some string is getting passed and making sure it's not empty. On the other, it seems to be a bit overkill, maybe if it was built in (Similar to IPAddress, EndPoint, URI and more), even though creating them is very easy using a record. For domain specific data, it's pretty obvious, and creating one seems natural, but going around and creating more 'basic' ones feels a bit overengineered. Would love to hear your thoughts!
@zoran-horvat
@zoran-horvat 8 ай бұрын
I am generally avoiding going into that direction because it quickly leads to the explosion of classes. However, I do apply it to domain concepts.
@ataadevs
@ataadevs 8 ай бұрын
I didn't understand how the AnyKeywordSatisfies function parameter went from Func predicate to Func predicate, can you please explain more or if you have any resources about it
@DragoGrayLite
@DragoGrayLite 8 ай бұрын
I think i should be called like: AnyKeywordSatisfies(keyword => keyword.Equals(phrase)) where the phrase is in predicate and it is not neccesary to have it in AnyKeywordSatisfies as input value.
@zoran-horvat
@zoran-horvat 8 ай бұрын
The missing string can be part of its closure - even more it can be some other type, not only a string! You can call that method with a lambda: keyword => keyword.Contains(x), where x is the local variable. This kind of solution is much more flexible than the first one.
@metallixbrother
@metallixbrother 8 ай бұрын
Thank you for an excellent video as always. I wanted to ask; what is the correct way to maintain value equality when using records that contain a collection, in your opinion? Is it better to create a type that wraps an immutable collection, that provides value equality for the contained collection and using that everywhere? This feels like it would be advantageous in that we don't need to create a custom equality comparer for every class that contains a collection, but a part of me worries that it might be a bit "hacky" as this is more dictated by how records handle equality checking on reference types, rather than being intrinsically meaningful.
@zoran-horvat
@zoran-horvat 8 ай бұрын
Collections have more than one way to compare, and that is the principal reason why they do not implement Equals and GetHashCode (besides the fact they would run in O(n) time and space often as much as O(n)). Therefore, I do not insist on maintaining equality in records that contain collections. It is more productive to supply an IComparer implementation that implements the desired comparison and leaves the record simple and focused.
@pl4gueis
@pl4gueis 8 ай бұрын
Do you have resources or a course for a complete end-to-end example of functional domain modeling in a complete application? I feel like connecting the dots between the immutable stuff and mutable stuff with side effects is currently a bottleneck for a lot of people.
@zoran-horvat
@zoran-horvat 8 ай бұрын
I am gradually building a set of demos, including in videos like this one, hoping to produce a comprehensive guide with a large demo at one point.
@luc9volts
@luc9volts 8 ай бұрын
Very good examples!!👍🏽
@baranacikgoz
@baranacikgoz 8 ай бұрын
It would be interesting if you make a demo using EF Core. If change tracker is not comfortable with this approach which it is not according to my demos, it is hard to use
@zoran-horvat
@zoran-horvat 8 ай бұрын
Entity Framework is designed for entities, whereas immutable classes, and especially records, are meant to design types and values. Those two things don't go together, in a sense that Entity Framework was never intended to operate on them. It is common to use plain access to a relational database (e.g. via Dapper and similar solutions), or to apply event sourcing. The latter, when combined with an immutable design, is especially well suited to cloud and network applications.
@ghevisartor6005
@ghevisartor6005 8 ай бұрын
@@zoran-horvat so confronting the two approaches, in your video "Kill Anemic Domain Models with Encapsulation: The Hard Part" you put the factory methods and other business operations inside the entity itself and then use that directly in the razor pages. I guess it wasn't for brevity for the demo, in case of razor pages or blazor server you would just those entities in the UI? The latest Blazor allowes you to swap between server or wasm render modes so maybe in that case one should consider the need for dtos unless they change how it works in the future (you need to make http calls in those wasm components anyway)
@Sydra.
@Sydra. 8 ай бұрын
This is the way!
@drbytes68
@drbytes68 8 ай бұрын
Cries in C# 7 maintenance program. Cant even use tuples
@zoran-horvat
@zoran-horvat 8 ай бұрын
True story. The language is so changed now compared to what it used to be.
@1992jamo
@1992jamo 8 ай бұрын
I am stuck with most C#7 to support some legacy systems as well, and until 3 months ago I hadn't heard of ValueTuple, most likely because I wasn't using them and online people referred to them as Tuples, which I had assumed were System.Tuple which I was familiar with. Within the last year I've been given the freedom to develop new applications and I've been trying to modernise my C# syntax & patterns. I'm going to specifically refer to them as ValueTuple in conversation to avoid confusion. edit: This comment appears to be publicly invisible for some reason?
@zoran-horvat
@zoran-horvat 8 ай бұрын
I think nobody mentions System.Tuple anymore, so you don't have to say ValueTuple explicitly. ValueTuples, or just tuples, have sent their inefficient and cumbersome predecessor, the System.Tuple, to a graveyard. System.Tuple was so inefficient, that I don't think anyone used them anyway.
@weluvmusicz
@weluvmusicz 2 ай бұрын
Immutables cost too much memory for a real world application!
@zoran-horvat
@zoran-horvat 2 ай бұрын
@@weluvmusicz What? You have no idea what you have said.
You’ll Never Write Functional C# Code if You Don’t Know This
6:20
What are DESIGN PATTERNS in programming - #programminginenglish
17:56
Programación en español
Рет қаралды 2,8 М.
«Жат бауыр» телехикаясы І 30 - бөлім | Соңғы бөлім
52:59
Qazaqstan TV / Қазақстан Ұлттық Арнасы
Рет қаралды 340 М.
Wednesday VS Enid: Who is The Best Mommy? #shorts
0:14
Troom Oki Toki
Рет қаралды 50 МЛН
Rock Paper Scissors Game with computer | Python Code
14:46
Mukesh Urmaliya
Рет қаралды 230
Master the Design of Functional Behavior in C#
19:17
Zoran Horvat
Рет қаралды 14 М.
How to Avoid Null Reference Exceptions: Optional Objects in C#
18:13
Eliminate Data Clumps: Step-by-Step Refactoring Guide
14:24
Zoran Horvat
Рет қаралды 12 М.
The fastest way to iterate a List in C# is NOT what you think
13:42
Nick Chapsas
Рет қаралды 160 М.
Master the Design of Functional Types in C#
17:53
Zoran Horvat
Рет қаралды 18 М.
Coding Shorts: For The Record - Why You Should Use (Records in C#)
10:46
Shawn Wildermuth
Рет қаралды 13 М.
The Return of Procedural Programming - Richard Feldman
52:53
ChariotSolutions
Рет қаралды 63 М.