I Was Wrong About Single Responsibility Principle | Prime Reacts

  Рет қаралды 84,251

ThePrimeTime

ThePrimeTime

Күн бұрын

Recorded live on twitch, GET IN
/ theprimeagen
Reviewed article: www.sicpers.in...
Become a backend engineer. Its my favorite site
boot.dev/?prom...
This is also the best way to support me is to support yourself becoming a better backend engineer.
MY MAIN YT CHANNEL: Has well edited engineering videos
/ theprimeagen
Discord
/ discord
Have something for me to read or react to?: / theprimeagenreact
Kinesis Advantage 360: bit.ly/Prime-K...
Hey I am sponsored by Turso, an edge database. I think they are pretty neet. Give them a try for free and if you want you can get a decent amount off (the free tier is the best (better than planetscale or any other))
turso.tech/dee...

Пікірлер: 255
@LZE.
@LZE. 8 ай бұрын
The problem with software engineering is that software engineers are too opinionated, in my opinion, as a software engineer.
@fus-ro-dah
@fus-ro-dah 8 ай бұрын
[forms an opinion software engineeringly]
@probaddie456
@probaddie456 8 ай бұрын
As a software engineer, I wish to state that, with completely unearned authority that, in my very specific and narrow experience in the field, and without regard to the fact that I lack knowledge in nearly all other ways in which the craft is practiced, and ignoring the well qualified opinions of experts in the profession, that you're dumb, stupid and wrong.
@InforSpirit
@InforSpirit 8 ай бұрын
Opinions, are stinky piles. Opinions with explanations, are golden. Only then you can argue, if gold has any value.
@eightsprites
@eightsprites 8 ай бұрын
I agree… and Im 100% correct
@MrAbrazildo
@MrAbrazildo 8 ай бұрын
I agree with Prime on this: _"A too opinionated junior is as dangerous as a senior with no opinions at all"_ .
@mattiasmartens9972
@mattiasmartens9972 8 ай бұрын
Per Wikipedia Robert Martin went on to rephrase SRP with a much clearer (and arguably quite different) meaning: "Gather together the things that change for the same reasons. Separate those things that change for different reasons." I like this. It's a good answer to DRY. For example if you are building an API for finance to view your sales, and an API for data analytics to view your sales, it is tempting to have them be the same API because at a small scale the difference between the two use cases are trivial to paper over. But at some point finance will start talking about bounced payments and fiscal years, and analytics will start talking about correlation IDs and shopping carts, and that's gonna lead to a sad time where you'll wish you'd duplicated most of that code from the jump.
@SewsAndCodes
@SewsAndCodes 8 ай бұрын
Hi! I wrote the article you're reading 👋🏻. Very interesting analysis, I think you're correct that a lot of software engineering knowledge is tacit and is gained by individual experience, but I don't necessarily think that that's the only way to do it. For example, Pete McBreen in Software Craftsmanship suggested a guild-like model where apprentices learn from masters; the point of that approach is that the master chooses the tasks for the apprenticeship that model all of the learning points.
@krccmsitp2884
@krccmsitp2884 8 ай бұрын
Another way of explaining what Uncle Bob meant in the first place: "One of the most foundational principles of good design is: ➡Gather together those things that change for the same reason, and separate those things that change for different reasons.⬅ This principle is often known as the single responsibility principle, or SRP. In short, it says that a subsystem, module, class, or even a function, should not have more than one reason to change."
@hungrymusicwolf
@hungrymusicwolf 8 ай бұрын
This is a principle I have been following for a while since it just made sense intuitively. It's good to know there is an actual name for it.
@NihongoWakannai
@NihongoWakannai 8 ай бұрын
The problem is that what counts as a "different reason" is debatable. And people have taken it to an extreme degree by splitting things up into tiny pieces. It's too vague to be used as some sort of ironclad rule that people do. It's just a general guideline.
@OMGclueless
@OMGclueless 7 ай бұрын
I still have no idea what "more than one reason to change" is supposed to mean. Every single line of code might have innumerable reasons for changing, and as I am not blessed with future sight, any understanding what those reasons will be is going to be just a guess.
@Reavenk
@Reavenk 8 ай бұрын
The issue is people focusing on what to do instead of why you're doing it. SRP is just a mindset to make the code easier to model and comprehend without random side-effects in execution and development. Which creates gains as the software starts to scale (or more accurately, doesn't create overwhelming whack-a-mole). It's a tool for wrangling chaos; if it doesn't in you're context, it's not useful, don't do it blindly. That applies to any principle.
@khatdubell
@khatdubell 8 ай бұрын
Found the smart one.
@GrantGryczan
@GrantGryczan 8 ай бұрын
This! So tired of hearing black and white opinions, from both sides: "[insert software design principle] is a bs principle and you shouldn't use it" or "[insert software design principle] is necessary for maintainable code". Be pragmatic on a case-by-case basis. Sometimes some principles are useful, and sometimes they aren't, and to determine that you need to think in terms of tangible costs and benefits.
@PieJee1
@PieJee1 8 ай бұрын
Well said. It also helps writing unit tests by testing everything more isolated. Of course there are times i end up with lots of classes with a constructor with dependency injection and a single public method and wonder if its too much. But then i have to replace one part and i remember why its beneficial
@BlazingMagpie
@BlazingMagpie 8 ай бұрын
I understand single responsibility as a way to reduce context overload. Having to keep a lot of context in head is the devil. My little brain starts to leak when I write more than 20 lines of code, so I write simple classes and functions that know little and do little, then compose them to do a little more.
@MrAbrazildo
@MrAbrazildo 8 ай бұрын
I've been using SRP conceptually, rather than a technical demand. So, I write a class that starts entirely read-only. As long as the project demands changes from it, I allow those specific locations to change it. It uses to vary from 1-10 f()s. The class ends up providing several functionalities around a goal. So it's not 1 technical thing strictly, but 1 single goal/matter/subject/responsibility. This has been pretty good for understandability.
@chudchadanstud
@chudchadanstud 8 ай бұрын
This is how I do it too. It's also pretty good at handling an evolving specification. SRP has saved me many times from massive rewrites mid project. I work in R&D so things can turn left real quick. SRP lets me Lego at anytime.
@Weaseldog2001
@Weaseldog2001 8 ай бұрын
Right. Once you understand that a relationship between objects is also a thing, the concept becomes s bit more useful.
@megatrongodzilla
@megatrongodzilla 8 ай бұрын
Make it work, make it pretty, make it fast , he often tells people the best way to start is "just to build the thing" make it work might be throw away but sometimes you need to know the problem space then you can make it fast.
@MrAbrazildo
@MrAbrazildo 8 ай бұрын
And for the last, make it pretty, if have time and if it's even possible.
@chudchadanstud
@chudchadanstud 8 ай бұрын
​​@@MrAbrazildoYou make it pretty to gain investment. Investors or your clients don't care as long as it's shiny. Making it fast should be the last thing you do.
@megatrongodzilla
@megatrongodzilla 8 ай бұрын
@@chudchadanstud I make it pretty because I code pretending the guy who has to maintain it will be a violent psychopath who knows where I live.
@MrAbrazildo
@MrAbrazildo 8 ай бұрын
@@megatrongodzillaThis is a known quote. You should give credits.
@MrAbrazildo
@MrAbrazildo 8 ай бұрын
​@@chudchadanstudIssue is that optimization conflicts with everybody. It's likely to destroy prettiness.
@az8560
@az8560 8 ай бұрын
It sounds like the idea is to create a separate module for each customer? Well, probably it could make sense... for some businesses... But probably the general idea of "don't glue your dog to your car, you don't want to take your car to the vet and your dog to repair service" is more useful.
@XxZeldaxXXxLinkxX
@XxZeldaxXXxLinkxX 8 ай бұрын
But I certainly do want to take my car to the vet, you expect me to walk or bike there like some sort of millennial?
@DavidvanDeijk
@DavidvanDeijk 8 ай бұрын
No, imagine a car factory with an assembly line. There are teams to support different parts of the car and the parts of the assembly line responsible for those car parts. Each module should correspond to a single team.
@pdgiddie
@pdgiddie 8 ай бұрын
​@@XxZeldaxXXxLinkxX You're aware that millennials are rapidly approaching 40 and probably have kids, right? 😂
@XxZeldaxXXxLinkxX
@XxZeldaxXXxLinkxX 8 ай бұрын
@@pdgiddie shut up
@asdqwe4427
@asdqwe4427 8 ай бұрын
My team knows typescript, the approved backend technologies at the company are node, java and kotlin. We’re going with node. Right tool for the job depends on who is doing the job
@blovio
@blovio 8 ай бұрын
The more I hear programming axioms that are widely used, the more I think you’re boxing yourself in mentally. Question everything, don’t take anything as given. Makes you come to your own opinions and try new things.
@Salantor
@Salantor 8 ай бұрын
Programming axioms are - maybe not all, but most of them for sure - a page from a book which was condensed into a paragraph which was condensed into a single sentence which was reinterpreted at least two times and is now used by people to throw at each other instead of explaining stuff. It's a decades long game of chinese whispers. "Premature opitimization is the root of all evil" is the greatest example.
@zealy1369
@zealy1369 8 ай бұрын
Then people hold it against you for not having any strong opinions, I've seen it when applying for senior roles, people want engineers who speak confidently to management about what tech or processes to adopt.
@kuhluhOG
@kuhluhOG 8 ай бұрын
@@zealy1369 not throwing around axioms and not boxing yourself in mentally does not mean not having strong opinions it means that you make up your own minds and ask for "why" to do something a certain way instead of "just because" or "because we always did it that way" and guess what, if you do that, you can stand your ground for your opinion way better than if you don't
@0xCAFEF00D
@0xCAFEF00D 8 ай бұрын
​​@@Salantor A fuller quote is so much better: "Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%." And I personally think the original context is along the lines of writing in bit hacks in the first implementation. This was 1974. Such premature optimizations must seem far more reasonable. The way I've seen it used today (haven't actually heard this for a long time now) is defending the extreme end of unoptimzied code. And what does passing up those 3% look like? Establishing unworkable interfaces, imo.
@SimGunther
@SimGunther 8 ай бұрын
​​@@SalantorEveryone forgets about the "must not forget about opportunistically seizing the easily obtainable performance gains that are significant" part of the Knuth's quote, yet here we are.
@jeffreybritton3338
@jeffreybritton3338 8 ай бұрын
After reading the SRP article on Wikipedia, my conclusion is the term is ill defined. Apparently everyone misunderstood the original definition and the clarification didn’t help matters any.
@jeffreybritton3338
@jeffreybritton3338 8 ай бұрын
I have given some more thought to the Wikipedia article. The end of it talks about Roles. I can imagine an app where there are Roles for sales, billing, returns, accounting, shipping, etc and these would be the SRP divisions. However one could also imagine UI and database as roles and then have to figure out whether these are horizontal layers or vertical layers. Does one group have UI responsibility for everything or does each role do their own UI. I’m sure there could be many more interpretations of the article. Some examples would be helpful.
@mathboy8188
@mathboy8188 8 ай бұрын
Isn't the concern about upfront performance considerations the worry that you'll be locked into architectural structures that will never be sufficiently performant? Conceptually, I try to consider that, but don't initially worry about performance in the lower level small details that can be relatively easily changed... for those I'm all in on _Make it work; Make it pretty; Make it fast_ (I'd add don't even try to make it fast at these lower levels until it's established that you need to... pretty is more important until it's proven that faster is necessary.) I try to think about big picture inflexible performance at the start, but mostly ignore performance in the details, provided those are details where you could relatively easily swap out doing it another way. At that level, it's often fairly straightforward to go from clean to performant if necessary. But the converse in my experience is not true... if you try to write the smaller non-architectural details as performant from the start, then it's going to be ugly and inflexible, and almost certainly will remain ugly and inflexible forever, and thus forever will be harder to understand and maintain. And very likely, that choice wasn't even necessary! There's a reason no one codes in assembly unless it's absolutely necessary. In other words, for these smaller bits, my view is that you don't want to make a mess in the name of optimization until it's demonstrated that necessity demands that you accept a mess in the name of optimization. _Pretty is more important than blazing performance "in general" (programmer salaries are the main cost of software dev),_ _and pretty to perfomant is a one-way street._
@ryanseipp6944
@ryanseipp6944 8 ай бұрын
I'm with you on the line of prime. That being said, I also prefer building infrastructure. Lower level things will be built upon to the point where every behavior will be depended upon. In that case, if you don't design with performance in mind, you'll never reach the optimum. On the other hand, Theo is more interested in getting products in front of users, all else be damned. Especially in a startup where the future is uncertain, that makes a lot of sense. The rewrite will suck, and you'll certainly pay for the mistakes later, but having revenue is the thing being optimized for
@SYSTEMlERROR
@SYSTEMlERROR 8 ай бұрын
If you can mock every component and test it without extra steps - it is solid. Its that simple. Srp depends on your interpretation of the term 'single' so there is no right or wrong here
@DryBones111
@DryBones111 8 ай бұрын
I like to teach the software interns SOLID to the point where they understand why the prescriptiveness of SOLID is bullshit. Rapid-fire footguns if you will.
@CottidaeSEA
@CottidaeSEA 8 ай бұрын
I like SOLID, but I prefer reality.
@moneymaker7307
@moneymaker7307 8 ай бұрын
That is the main problem with software development You are teaching other people a concept you your self don’t truly understand. The idea of single responsibility principle and most of the concepts uncle bob was trying to teach actually came from engineering. These concepts are foundations in mechanical and electrical engineering. The reason you can get by without following solid principles is because failure in context of the web is not as disastrous as failure in other fields of engineering. If you can write software for critical system without following solid principles, then you have probably discovered a new profound way of building systems. Instead of thinking of software only context of the web, start thinking of software from that perspective of engineers trying to build a car or why a component in a Samsung TV can work in a Panasonic TV. My point all these principles works in other fields engineering including software development dealing with critical systems. English is not my first language, but hope I was still able to get the idea across.
@CottidaeSEA
@CottidaeSEA 8 ай бұрын
@@moneymaker7307 If you can write a function, you can create a singular unit, just like an engineer can create a component for a TV. SOLID is really not necessary, but the things taught by it are valuable even if not strictly followed.
@Yupppi
@Yupppi 8 ай бұрын
I've been thinking: is software engineering all about trauma handling and self-help, because everyone seems to tweet and write blog posts that are aiming to be insightful life-coaching (or ranting about social aspects) or perhaps philosophical paths. It feels fundamentally different to any other engineering to me (or I haven't been exposed to this side of other engineering fields).
@ea_naseer
@ea_naseer 8 ай бұрын
science starts from philosophy what we are witnessing in the SE world right now is a bunch of "Greek philosophers" arguing and creating their own schools of thought. It would take a while before anything becomes scientific.
@theodorealenas3171
@theodorealenas3171 8 ай бұрын
I hate programming video titles, "you should use deez nuts," "your mum is DEAD use deez nuts instead," "you've been using deez nuts wrong for 4 years now," do this do that stop this start that like SHUT UP you and your daddy issues! Don't tell me what to do, I'm an adult! And the people face to face as well by the way, they think he only thing someone can say is either advice or criticism, there's no way they just want to share their experiences, if they exposed something personal they're definitely asking for advice or they're trying to criticise you in disguise. I don't think it was that bad with drawing, the communities were calmer.
@TheHackysack
@TheHackysack 8 ай бұрын
@@theodorealenas3171 Dude, I died laughing while reading this. Thank you.
@yessopie
@yessopie 8 ай бұрын
My rule is, "don't follow a rule that you don't agree with". If you don't agree with the rule, then either: 1) it's a stupid rule; 2) you don't understand the rule; or 3) you don't understand what following the rule is supposed to accomplish. SRP was never supposed to be about having only a single "change point". When they saw this, they should have thought, "Do I agree that a module should only have a single change point? I need to be convinced before I do this." But now we're at a point where new programmers are just blindly following (and misunderstanding) the advice of previous generations of programmers instead of reasoning from first principles.
@theodorealenas3171
@theodorealenas3171 8 ай бұрын
I love that rule. I'm in Uni and we throw phrases like "productivity," "maintainability," "just a good practice in general" and so on so cheaply sometimes. I don't think we need to set up a stopwatch to measure productivity but without some kind of evidence or experience maintaining software we're just making guesses.
@theondono
@theondono 8 ай бұрын
The key part of uncle’s Bob point is “originate”. The situation to be avoided is that Team A requests you to set n=5 but Team B requests you to set n=3000. If both Team A and Team B have a say in setting n, they need to sit together and find a compromise first, then make a joint request to set n.
@Arcwise
@Arcwise 8 ай бұрын
The 3 stages of SRP: 1. Using it wrong by implementing “the class should only bear 1 responsibility” (as per its name) 2. Using it wrong by implementing “the class should only have 1 reason to change (as per its definition) 3. Using it right after having read the full Wikipedia article or any of Uncle Bob’s books but being bullied by the community for being a “clean coder”
@nickr753
@nickr753 8 ай бұрын
"There should be only one reason to change it" is better understood as there being only a single person or role within the organization who would be responsible for a decision to change the class. For example, if the class is an implementation of a business process defined by the org's director of finance, then only a decision by the DoF to change that business process should result in a change to the class. This is related to Conway's Law (no relation to the Game of Life) -- "Organizations, who design systems, are constrained to produce designs which are copies of the communication structures of these organizations."
@barongerhardt
@barongerhardt 8 ай бұрын
The end bit about problems with software engineering is the difference between technical knowledge and practical knowledge. Technical knowledge is the knowledge that can be adequately described so that it can be passed to another. Practical knowledge is knowledge that can only be acquired through practice (experience). Reading and fully comprehending every book ever written about boxing won't stop you from getting hit in the face. Software engineering is the study and creation of that body of technical knowledge. It can be improved, but it is highly flawed to think that it could ever eliminate the need for developing that personal practical knowledge.
@danielmelo389
@danielmelo389 8 ай бұрын
I work with Visual Basic and came here to say, Please, please don't.
@electrolyteorb
@electrolyteorb 8 ай бұрын
I program in BASIC... I also have much of the same opinion
@yash1152
@yash1152 8 ай бұрын
6:41 i agree with ur take - butttt the institutions and things can make you do those "over-and-x4" part with some small guidance on what to do over-and-x4.... maybe???
@peteruelimaa4973
@peteruelimaa4973 8 ай бұрын
Bob just always claims being 'misunderstood' when he notices he was wrong.
@DizzyThermal
@DizzyThermal 8 ай бұрын
Prototyping helps me make a bunch of mistakes up-front, which sometimes can help me understand how to optimize what I'm creating. If everything I'm writing against is well documented, I may not need the prototype, but that may not always be the case.. I do agree that a lot of projects and companies ignore their technical debt until it's too late though, that's a fact!
@TheGhost152
@TheGhost152 8 ай бұрын
The problem with trying to make anything new "perfect" from the start (e.g. it works & its cost effective, or it works & its fast, etc.) it will most probably take way too long. By the time you are anything close to a finished product whoever is paying you to make it (investors or parent unit or whatever) has already pulled the funding. Just make it work first such that they can smell the money, then redesign it to be fast/low cost/whatever. Yes it takes overall longer time, but has a much higher chance of securing full funding.
@andyk2181
@andyk2181 8 ай бұрын
Delivering a prototype can take the pressure off, the downside is that people inevitably underestimate how long it takes to go from prototype to finished product.
@aakarshan4644
@aakarshan4644 8 ай бұрын
Just write shit that works and then decouple a little and avoid unnecessary abstractions.
@Salantor
@Salantor 8 ай бұрын
And if you really need architecture just design it along the way. And if you want to use gazilion of libraries then pick them first, arrange your code around them and just proceed.
@adambickford8720
@adambickford8720 8 ай бұрын
I remember working on a java thick client and there was more effort around if it was 'real mvc' than solving the users problem. Don't lose sight of the actual goal.
@chipdenman863
@chipdenman863 8 ай бұрын
In nuclear engineering SRP means you have a single point of accountability (blame).
@pinatacolada7986
@pinatacolada7986 8 ай бұрын
The Single Responsibility Principle is absolutely incredible for writing CSS. For other programming languages... not so much.
@SevenRiderAirForce
@SevenRiderAirForce 15 күн бұрын
There are a lot of fantastic ideas that get overly condensed and then misunderstood. The rational actor in economics is another such example - it's an extremely useful psychological insight, yet it's widely misunderstood due to the difference between the technical and the vernacular definitions of "rational."
@elimgarak3597
@elimgarak3597 8 ай бұрын
The fact that these principles are so ambiguous and raise so many different interpretations is telling. Can't software engineering be less subjective and more scientific? Or at least more empirically informed and less one-enlightened-messiah-at-the-mountain driven?
@RoadsideCookie
@RoadsideCookie 8 ай бұрын
A lot of software engineers didn't even go to school, so it would be hard to make that the norm.
@sampruden6684
@sampruden6684 8 ай бұрын
IMO these standard principles are far too general, and the best course of action always depends on the specifics of your application and its requirements. People need to learn to deduce their own principles from their specific problem instead of following vague guidelines they've read but not understood.
@GA-fs4cz
@GA-fs4cz 8 ай бұрын
@@RoadsideCookie You cannot call urself software engineer without a proper university. Coder, yes, but you are not an engineer.
@natescode
@natescode 8 ай бұрын
No. Just like religion, the power comes from your own interpretation to justify your actions
@Bozebo
@Bozebo 8 ай бұрын
@@RoadsideCookie I did and it just made me worse than I was before I studied. Universities seem to push these static ideas the most. Probably because they can only help so much with the rest, you have to just go for it and learn through experience.
@drxyd
@drxyd 8 ай бұрын
I often don't know how to make it fast until I get it working in at least 2 different ways.
@meiliyinhua7486
@meiliyinhua7486 8 ай бұрын
Honest question: do most codebases have any sort of documentation with some sort of scale of "don't fuck with this unless you really need to" in there? Like so if you were going to maintain a dependency of some sort, you would see where it is on the scale relative to downstream and upstream packages, and make an informed decision about whether maintaining that dependency is better than rewriting (or copying over with bug fixes and/or new features, and using *that* for your new dependeency chain?
@rickwoods5274
@rickwoods5274 8 ай бұрын
"Build a working copy, then refine" -- no. *Prototype* a working copy, then _scrap it and build it right_ is great.
@blubblurb
@blubblurb 8 ай бұрын
I'm currently working in a project which was built exactly like Prime describes it after the 4 minutes mark. Things were just programmed so that it's "done". The App is very slow now. My job is to make it more performant. Biggest problem, data was structured to be written very fast and then transformed when shown in the UI. The data is read like at least 100 times more often then written. Next problem was that no one read the docs on how to use the framework properly. A lot of choices inside made it very slow and rerender the UI way more ofthen then necessary. IMHO, those things should have been designed differently from the start.
@thesilph
@thesilph 8 ай бұрын
A lot of the these "rules" were made at a time where everything was in the same big monolith box, and there it might even make sense most times. Some stuff about PEOPLE in software can be right forever maybe, like stuff from Fred Brooks. But the "totally right way" stuff like this worked was almost never planned and written with a distributed system in mind for example, or even most client-server interactions. I could be wrong of course, but It's how I feel about it
@steveoc64
@steveoc64 8 ай бұрын
A SOLID function must have an even number of lines, an odd number of words, and use a number of chars that fit the Fibonacci sequence.
@RandomGeometryDashStuff
@RandomGeometryDashStuff 8 ай бұрын
05:17 good luck with file manager in scratch (there are no blocks for file system)
@matheusdemoura5529
@matheusdemoura5529 6 ай бұрын
I think applying good methods is more important than experience itself, and good practices and principles are important for that purpose... people unfortunately will screw things up because its human nature to reason excuses not to do what we know it`s right, because it's hard.
@Jabberwockybird
@Jabberwockybird 8 ай бұрын
So is SRP more akin to having code that is owned by a full stack team maybe?
@boccobadz
@boccobadz 8 ай бұрын
Fake it till you make it in a nutshell - 99% of so-called software developers haven't read any proper books (and not even JS docs if sth like isArray dependency exists) and they keep parroting what others have written on the forums. Besides, most of those "rules" were invented in a different age - it's like coding in punched cards era - definitely cool during its time, but not really applicable in the modern age.
@justanothercomment416
@justanothercomment416 8 ай бұрын
Best practices in many case evolved to become so because they cured a lot of issues. A very common problem is that which you specifically mention. In that younger devs are ignoring best practices because they falsely believe they no longer apply. The result in many projects are suffering many of the old problems which created the need for the best practices in the first place. A common issue in both culture and coding is many times people pass on traditions (best practices) but fail to explain why they exist in the first place. This gives the impression they are optional or simply something of a bygone era. As a result, people begin to recreate the very problem these "optional" practices resolved decades ago. I'm not saying you're necessarily wrong. I'm simply saying be careful. I've personally observed far too many people step on the landmines created by such a progressive mentality. Accordingly, it may be a failure of those before to properly pass on the lessons learned.
@mindasb
@mindasb 8 ай бұрын
Single Responsibility Principle works better and better the smaller the abstraction level we apply it to. It is axiomatic in statements and expressions. It is easy in functions. It becomes OK-ish, but questionable in classes. It becomes stupid in groups of classes (modules/packages It becomes just nonsense on a project (application / library / framework) level. ... Unless you are willing to inflate what the meaning of "responsibility" is.
@RoadsideCookie
@RoadsideCookie 8 ай бұрын
But if you inflated it at each level, it starts making a lot of sense and in my experience results in code that is extremely easy to maintain and collaborate on.
@mindasb
@mindasb 8 ай бұрын
​@@RoadsideCookie I agree with that and I like SRP - it's one of the easiest design principles for my students to understand. My point was that beyond class level it can lead to confusion rather than guidance (easpecially if you are new to a problem domain).
@bobbycrosby9765
@bobbycrosby9765 8 ай бұрын
Given the definition outlined in the article, at the module/project level isn't it kinda a bounded context in domain driven design?
@isodoubIet
@isodoubIet 8 ай бұрын
This interpretation of the SRP seems fundamentally confused to me. So what, if a program is developed by a single person it can just be a giant ball of spaghetti and still satisfy the SRP? Makes no sense. Personnel organization will often be reflected in the code more-or-less unavoidably, no sense or reason in turning that into principle.
@JoseCarlosVM
@JoseCarlosVM 7 ай бұрын
A business need implicating in changes across several modules doesn't mean that each module's change wasn't the result of an individual business need. One business need -> many modules != many business need -> one module
@ElvenSpellmaker
@ElvenSpellmaker 8 ай бұрын
I believe we've been trying to idiot-ify development for ages. I agree readable is often a good thing. Buuuuut, hot take here: I wrote a system for pagination with filtering in PHP and the code wasn't nice to look at. It even used goto at one part, but it did well, and as fast as PHP basically could given the framework (Falcon) and SQL layer provided. It got merged but much gritting of teeth was done, and Devs said it wasn't all that readable or extensible. The devs who merged it clearly didn't quite understand some of the stuff I did but it worked. Anyway go forwards a few months, we got this new dev in, he picked it up and extended it within his first sprint there. Bam, no problems whatsoever, it just took a dev worth his salt and someone who could reason code.
@theodorealenas3171
@theodorealenas3171 8 ай бұрын
Why is it like most of the comments came from people who didn't watch the video? They're talking about the first part of the video, that says the misconceptions about SRP and not the second part of the video that untangles it
@arkie87
@arkie87 8 ай бұрын
the problem with software engineers is they will learn a concept and then take it to the extreme in every context even if it doesn't make sense, requires extra coding/verbosity, or is much harder to read. It is important to understand the reason behind the concepts so that one can determine when it makes sense or pays to apply them. I like your takes on things. Uncle Bob and go Uncle Bob himself.
@dickheadrecs
@dickheadrecs 8 ай бұрын
“Uncle Bob, this is Enrique”
@shapelessed
@shapelessed 8 ай бұрын
I hate the "only use this design pattern" or "single responsibility" folks. Would you really want to instantiate everything with pure functions? And SRP? Take a look at caching. Some piece of code will eventually have to have some side effect aside from returning your content in order to cache it... Sometimes these opinions are too opinionated...
@Wielorybkek
@Wielorybkek 8 ай бұрын
I am confused, I remember Prime saying he writes something just to prototype and learn only to throw it away and rewrite but in this video he talks about designing your software in an early stage. so, how to live?
@xTriplexS
@xTriplexS 8 ай бұрын
In the video he's talking about making an actual product that'll be used once it's done and will be improved over time
@shiftysharpe1234
@shiftysharpe1234 8 ай бұрын
I would think of the prototype being part of the discovery during the design phase. Rather than the output of the design. He was likely talking about alpha/beta stage needs to be designed with some roughly appropriate scales in mind in the point you reference. If you know at the design phase you need to scale big in some way, they you design for that in the product you build (not in the prototype)
@isodoubIet
@isodoubIet 8 ай бұрын
The "throwing away" part is important
@theodorealenas3171
@theodorealenas3171 8 ай бұрын
I swear though, when I prototype and I show demonstrations to my Uni teammates, they get so confused like they're seeing a UFO. You'll commit that thing? Oh you won't? I mean you will right? No he said he won't... But he will, right? Look at it.
@Bytekeeper
@Bytekeeper 8 ай бұрын
The best way to learn software development is not to see how its done "right" first. It's letting you do it wrong a few times until you find a good solution. Or you see the point of there being a "right" solution.
@PieJee1
@PieJee1 8 ай бұрын
On one side you have people who have trouble handling more than a few source codes open at the same time and i see they prefer god objects.. they tend to write integration tests to test your code. You also have people that prefer smaller files for conprehension and they use SRP more. They tend to run unit tests. I am in the SRP camp. 😂
@Trae4k
@Trae4k 8 ай бұрын
I feel like loosely coupled code is way better at explaining how you should approach single responsibility. It shouldnt be over engineering just so you dont have to make a change in 2 places either.
@clachdhearg2109
@clachdhearg2109 8 ай бұрын
a lot of the wisdom from old se heads comes from careers working in large corps where you had to manage org complexity as much as software complexity esp w/ change management pre-standardized source control.. its worth understanding but good chance it doesnt apply anymore we have different paradigms now
@justanothercomment416
@justanothercomment416 8 ай бұрын
Advocating premature optimization is the root of all evil. Your position that evil is good is inherently a major red flag on your engineering skills. Make it work, means prototype it to make sure you understand the problem domain. A functionally correct implementation is frequently contrary to performance requirements. Yet understanding the problem domain significantly reduces bugs. Your next step is to move it from a functional implementation, which may be ugly, into something pretty and maintainable. This allows for a "pretty" implementation which facilitates adoption and maintenance. Here you stop unless you KNOW performance requires improvement. You require empirical datum to move to the optimization step. Given that you have confirmed you have mastered the problem domain you are now in a position to create a better, faster, stronger, implementation which may be contrary to easy comprehension and maintainability in exchange for the performance requirements. Optimization is frequently contrary to readability and maintainability. Essentially creating a fragile surface. Premature optimization is the root of all evil. Anyone preaching otherwise is flagging themselves as a potential issue for the project and team. As well as raising basic questions of their general competency.
@Salantor
@Salantor 8 ай бұрын
"Premature optimisation is the root of all evil". Funny, you are using only a part of the quote and misinterpreting it at the same time.
@justanothercomment416
@justanothercomment416 8 ай бұрын
@@Salantor I don't believe I'm misrepresenting it in any way. Given I have decades of shoulder rubber with fellow engineers who all understand it to mean the same thing, please educate me and an entire generation. BTW, much of my career is that of the "optimization guy."
@Salantor
@Salantor 8 ай бұрын
@@justanothercomment416 Ok, I was not sure but now I see you are just shitposting. That is fine though, carry on!
@justanothercomment416
@justanothercomment416 8 ай бұрын
@@Salantor Your projection is obvious. I politely asked for you to substantiate your position. In both of your comments you did precisely what you now accuse me. That's very dishonest and manipulative of you. Perhaps you should educate yourself instead of attempt to project anger, ignorance, and hubris upon others. The first is helpful to yourself. The second is not helpful to anyone and harmful to you.
@Bozebo
@Bozebo 8 ай бұрын
It depends what problem you're trying to solve and what the limitations are. I agree most projects these days do not need optimisation first. Build then profile, then adapt. It's usually not hard to throw some parts away and build them better. But some problems need a very clever starting point or the end goal will become unreachable as everything in the middle depends on the fundamentals which had to be right (see: much of game development).
@bobbycrosby9765
@bobbycrosby9765 8 ай бұрын
SRP is the source of so much bikeshedding.
@hackmedia7755
@hackmedia7755 5 күн бұрын
Theres bad examples where they show only one method for a class. It's a wrong perspective, single responsibility means grouping methods into that one topic. For example Network class that contains connect, disconnect, and getData methods
@AshtonMotana
@AshtonMotana 8 ай бұрын
My favorite programming paradigm is where I can create what I imagine.
@kyoai
@kyoai 8 ай бұрын
SRP in software is like building a house where every room is only responsible for one thing : one room for sleeping, one room for storing clothes, one room for eating, one room for watching tv, one room for storing food, one room for storing drinks, one room for storing dishes, one room for washing dishes, etc. A good idea in theory, but often it makes sense to merge things together.
@NihongoWakannai
@NihongoWakannai 8 ай бұрын
You could also further split rooms into "room for eating cereal, room for pouring the milk, room for putting the cereal in the bowl, room for holding cereal spoons, room for holding cereal bowls, room for cleaning cereal bowls" What counts as a "responsibility" could be granularized to an absurd degree. When splitting things into classes, you need to be making an active decision about what responsibilities are actually important to split and which are fine to just keep together.
@SingletonSean
@SingletonSean 8 ай бұрын
I really like this analogy
@finickyflame
@finickyflame 8 ай бұрын
What you've explained is not SRP, it's "Separation of concern". SRP is basically your house should only change when you ask your contractor (developer) for a change. It shouldn't affect your neighbour's house. Basically, one actor is responsible for the changes toward a module (your house).
@GrzegorzNyga
@GrzegorzNyga 8 ай бұрын
Where can I watch VODs from this live streams?
@petercfraedrich
@petercfraedrich 8 ай бұрын
I think the fundamental disagreement about the work/pretty/fast thing is that you _shouldn't_ commit your code after the "work" stage, only after the "fast" stage.
@ifstatementifstatement2704
@ifstatementifstatement2704 8 ай бұрын
It’s all arbitrary. That’s what people in software refuse to accept. It justifies their shitty behaviour towards others, so they will never accept.
@Archheret1c
@Archheret1c 8 ай бұрын
"Get a working copy then refine it" I´ve worked on too many such projects, the truth is that they never get refined.
@dehb1ue
@dehb1ue 8 ай бұрын
So SRP is a corollary of Conway’s Law?
@ysayius
@ysayius 8 ай бұрын
SRP exists to to explain to people why writing an app as a 10,000 LOC flat file is a bad idea (which is still a very common sight). I think this article got a bit too big brained and nuanced about what I think is basically a club I use to bonk heads
@zzeck431
@zzeck431 8 ай бұрын
I have always despised SRP because the quick definitions people read lead to this interpretation, and I can never seem to persuade people what they are doing is manifestly insane. It gets worse when people have even heavier weight ideas of what a proper "module" is. You think micro functions are bad? Wait until you have micro classes, interfaces. Oh that isn't enough? Maybe the modules are aws lambdas. Then you have folks dumping *pieces* of SQL query builders into dedicated AWS lambdas in the name of "SRP". I wish I was joking. I literally have been on a project that did this very thing. SRP even in the good form, is almost vacuous advice, and still horribly horribly misleading. Is a sword single responsibility? How many game systems does a sword interact with? Overworld, crafting, battle? What data is needed? Should all that data be in one struct? The reality is, you probably have a slightly different representation of the sword in all those systems, that have functions which go among them, or look up tables. The relevant aspects of something depend on the goals of the model. You get beginners trying to build some insane platonic ideal of "the singleness" of some "concept" that could serve all future needs, a universal model, with universal elements. They also are fixated on using ONE kind of modularity, usually classes, as the only legitimate container of these "single responsibilities." A private function is not enough for them. They never learn to analyze a concept, and then implement it using the most limited, appropriate language feature, or piece of technology. SRP is advice that can be only misunderstood by beginners, and experienced people who know what it is poorly gesturing at, don't need it. Tell beginners to focus on finding the minimal required data/information to implement a particular task. Tell them to find the most constrained, most precise, well fitting language feature or piece of technology to implement that. ("Do I need private mutable state to hold this string? Is it ever going to change at runtime? No? Even if it did, would we have to change the codebase much to deal with that WHEN it happened? No? Then why is it in a private field retrieved by a virtual method, in a class that's also implementing this method as part of a dedicated interface?") Tell them almost anything except SRP as starting advice.
@zzeck431
@zzeck431 8 ай бұрын
The basic reason it is outright pernicious, is because the developer is always CHOOSING what counts as "responsibility" for this analysis, but beginners never are aware of this choice. Their initial unanalyzed intuitions become law, and yet they feel these decisions have the full weight of best practice and authority behind them, thinking they are the only possible answer one could derive from SRP. It's a kind of debilitating brain rot almost impossible to shake people out of. At best, they feel guilty if you have them do a different sort of analysis, and at the worse they act like you're a moral leper, breeching objective truths about what the project's architecture should be, as dictated by SRP.
@salameez
@salameez 8 ай бұрын
Another day of this dude flaming fp without even knowing a fp language.
@JuusoAlasuutari
@JuusoAlasuutari 8 ай бұрын
All my classes are shit code, that's the secret of their uniformity and simplicity.
@Bozebo
@Bozebo 8 ай бұрын
In other words, should is a different word from must.
@alexandervasylevskyi1332
@alexandervasylevskyi1332 8 ай бұрын
Can't agree more that you need those thousands failures. I had couple of great teachers which knew all the software architecture concepts and explained them like they've created them. But one day they've decided to start coding. And boy it took long time for them to apply their knowledge
@michaelcombs5287
@michaelcombs5287 8 ай бұрын
You call it brain rot, we call it: "no ... u"
@-Jason-L
@-Jason-L 8 ай бұрын
SRP is responsible "to", not responsible "for".
@code-dredd
@code-dredd 8 ай бұрын
Unfortunately, I think we should be called software artists, and mentorship and/or progression might benefit from the approach chefs take when training the next generation. Something to think about...
@MehranGhamaty
@MehranGhamaty 8 ай бұрын
The only reason to change something is if it's broken.
@greycell2442
@greycell2442 8 ай бұрын
This guy here.... he wants one input and multiplex outputs. You have to take it with a grain of salt, otherwise you walk into oop land without realizing. I wouldn't get hung up on it without a concrete example that frustrates him. SRP wasn't created for higher level, like oop or microservices. It wasn't envisioned like that, as if there were ancient prophets that knew what was coming. It was about the smallest unit.
@jeremybuckets
@jeremybuckets 8 ай бұрын
Damn I wanted to hear what he was about to say at the end
@goldensunrayspone
@goldensunrayspone 8 ай бұрын
learning is very much like navigation, you can do math and give me gps coordinates and give me maps and general guidelines, but in the end, I'm only going to make it to my destination by putting my fucking boots on and walking.
@antonmaier2263
@antonmaier2263 7 ай бұрын
why is he always marking text without last and first letter?
@chudchadanstud
@chudchadanstud 8 ай бұрын
"Make it work, Make it pretty, make it fast" is how you keep your job and grow your business. On the top of my head I have not heard of a single successful company that has succeeded by optimising first. The mantra applies in all fields of engineering. The first cars were ugly and slow, but they worked.
@saniel2748
@saniel2748 8 ай бұрын
This only works if you have literally no competition in the field You are not building a videogame without keeping performance in mind. You're not competing with discord by making app that takes longer to load and is laggy asf (hello guilded)
@NihongoWakannai
@NihongoWakannai 8 ай бұрын
Wrong. Do you think new cars are built slow and bad first and then they make a new version that's better performant? No. All new cars are designed well on paper first, they are never anything close to what cars were like 100 years ago. If you're inventing something 100% brand new and doing prototypes then sure that's fine. But most people are not inventing anything new, you know what you're making and you should be able to make it to an acceptable degree in the first try. Take videogames for an example, youu HAVE to make them from the start with good architecture in mind. If you don't, then you'd basically have to refactor the ENTIRE codebase in order to make it more performant. That's not economical.
@chudchadanstud
@chudchadanstud 8 ай бұрын
@@NihongoWakannai No, I'm saying when Benz was building the first car he wasn't worrying about it's looks or performance. He just wants the thing to work. It was the same with the Wright Brothers, Mark Zuckerberg, Nokia etc. The first XBOX was ugly even. They needed proof of concept. Then they can iterate on it an improve. The looks came second because they needed funding and the needed attention on their product. Optimisation is the last thing. This is because it's the hardest and longest process.
@chudchadanstud
@chudchadanstud 8 ай бұрын
@@NihongoWakannai Try to optimise early and you will run out of money before the product even launches.
@chudchadanstud
@chudchadanstud 8 ай бұрын
@@saniel2748 99.99% of software engineers aren't building games. Most games aren't even optimised lol. Facebook would have literally failed if they started out by optimising. Your competitors is always one step behind you. Get your ideas out before they do, polish later.
@khhnator
@khhnator 8 ай бұрын
i feel like i missed the context that this conversation happened
@mintx1720
@mintx1720 8 ай бұрын
I feel like SRP is a good justification to make random claims and nothing more.
@NihongoWakannai
@NihongoWakannai 8 ай бұрын
I completely 100% disagree on "we can't teach people, they just need experience" Software engineering is not some completely unique special field separate from every other one where you can only learn through experience. Just like EVERY OTHER job and field in the world, good software engineering can be taught. Sure, you need experience *as well* because you can never be good with *just* studying, but to say that bad software engineering teaching "can't be fixed because people just need experience" is categorically false.
@ea_naseer
@ea_naseer 8 ай бұрын
the field isn't matured. there is a specific set of maths needed to build a bridge there isn't even a stochastic equation for managing memory properly. You pick a paradigm whether it's a queue based, priority system etc and then deal with the consequences. The field is not scientific so you do have to MOSTLY LEARN from experience.
@NihongoWakannai
@NihongoWakannai 8 ай бұрын
@@ea_naseer whether or not it's scientific has no bearing on whether it is teachable. Every single field of knowledge in history has had generational knowledge transfer, software engineering is not special. If everyone is having to rely on personal experience, that's just a sign that we're terrible at teaching new generations.
@csabaczcsomps7655
@csabaczcsomps7655 8 ай бұрын
SRP is complete when any programer read the code say "this is funny".
@msc8382
@msc8382 8 ай бұрын
This scares me. I see a lot of comments saying engineers with opinions exist. This is very dubious. Engineering is about identifying a problem without opinionation in a systemic/predictable way where every step produces the means to relate part of the solution to a problem, and then apply the smallest solution that solves the problem. Developers who don't apply engineering principles do the work based on opinion. And as quality assurance lead with 10 years of multi diplinary language experience, those people cause me the most work and consistently too. If you can't do your work without opinion, you're not engineering. If you disagree, please elaborate how. I'm very open to be shown different perspectives.
@jonludwig1632
@jonludwig1632 8 ай бұрын
As a tech artist working with performance optimization for games, the pitfalls of "make it work, make it pretty, make it fast" is something I am constantly on about.
@NihongoWakannai
@NihongoWakannai 8 ай бұрын
Games definitely require a proper architectural approach from the start. A naive implementation to get the basic functionality for a game can be completely different to what would be needed to scale that game fully.
@SimonBuchanNz
@SimonBuchanNz 8 ай бұрын
Is that the original order? I remember "work, fast, pretty" as the order, and even there there's the necessary interpretation of "fast" meaning "fast enough", though being a tech artist perhaps pretty means something else 😅 I would think getting something working first is still really important though: how else would you know if you even want the thing you're trying to make? Maybe you're talking about things like doing upper-bounds tests to see if it's even theoretically possible to get a reasonable performance?
@brandonpearman9218
@brandonpearman9218 8 ай бұрын
I dont agree that its about experience. There are soooo many devs with experience of 10+ years that are far worse that 4year experience devs. The guys that get good are all the ones that read and learn.
@christopherparke9878
@christopherparke9878 8 ай бұрын
I actually see the SRP totally differently. My take on it is that you want a module to do one thing, and if it needs to do something else, that should be a new module. The reason for this, is when you want to change or add something later, you don't have to change a monolithic module. It essentially tries to provide a rule that can help minimize backtracking.
@ShowNoMercy
@ShowNoMercy Ай бұрын
it is. srp = no 5k rows god classes
@hamm8934
@hamm8934 8 ай бұрын
Programmers really need to take a day to understand what the word convention means and what it doesnt mean
@Salantor
@Salantor 8 ай бұрын
Programmers need years off to rethink a lot of words and concepts related to programming.
@0oShwavyo0
@0oShwavyo0 8 ай бұрын
Programmers hate principles because they treat them like laws. If it’s going to make your program worse to divide up the responsibilities any further, then just… don’t… Doesn’t mean it’s not generally a good idea to separate out different responsibilities into different modules/classes.
@Salantor
@Salantor 8 ай бұрын
Funny how concepts list DRY or KISS or SOLID are so widely known and used, yet a lot of the time people don't know when to just drop them.
@hamm8934
@hamm8934 8 ай бұрын
@@0oShwavyo0 exactly
@Bozebo
@Bozebo 8 ай бұрын
Yeah I summed it up in my root comment. Should has a specific meaning, it is not the same thing as must. It must be secure and fit for purpose, the rest is generally debatable. Cynically actually, it doesn't have to be fit for purpose if you have good marketing or the contract is silly in the first place just keeping some middle manager around to draw a pension and nobody wants it :)
@ollydix
@ollydix 8 ай бұрын
In my day the hot take was 'everything singletons' and you'll be ok.
@ThePrimeTimeagen
@ThePrimeTimeagen 8 ай бұрын
still sort of popular
@rogergalindo7318
@rogergalindo7318 8 ай бұрын
totally unrelated, but you should definitely watch this video, is great, by the guy of “this is my favorite linux command” I Spread Dangerous Misinformation (Apology Video)
@samick9000
@samick9000 8 ай бұрын
ThePrimeTime, still a very nice gentlemen. Thanks.
@chickenmonkey88
@chickenmonkey88 8 ай бұрын
People need to stop wasting their time trying to decipher the prophecies of Uncle Fraud.
@potato9832
@potato9832 8 ай бұрын
The problem with software "engineering" is everyone thinks their farts smell like roses and everyone else's farts smell like gut rot. Design never gets better than my opinion vs your opinion. Nobody is correct and everyone is correct. It's an endless circle of nitpicking other people's nitpicks.
@mehdi-vl5nn
@mehdi-vl5nn 8 ай бұрын
2:28 I do not :(
@LightArtsOfficial
@LightArtsOfficial 8 ай бұрын
Can you please increase the volumne of your voice in the future videos?
@electrolyteorb
@electrolyteorb 8 ай бұрын
Just rewrite React in QBASIC, or the other way around
@ike__
@ike__ 8 ай бұрын
I would disagree about you disagreeing with the ‘make it first then optimize’. This is literally just prototyping, if you don’t fundamentally understand the solution how are you supposed to make optimizations AND be in-depth with your analysis
@sampruden6684
@sampruden6684 8 ай бұрын
This has two problems in the real world: - The easy solution and the fast solution often look very different. Your prototype teaches you how to build the bad version. It doesn't necessarily help that much with how to build the good version. - Nobody actually treats their prototype like a prototype - i.e. throws it away and starts from scratch. They try to iterate a few hotspots towards good, which fails because the good solution is usually quite different in structure.
@ike__
@ike__ 8 ай бұрын
@@sampruden6684 those are valid points, with the second point I assume the reason is time constraints and since I have only worked on projects with neither/long ‘deadlines’ I could throw away my prototype as ‘research’. Thanks for the comment!
@jpratt8676
@jpratt8676 8 ай бұрын
I don't think the take at the end of the video is acceptable. We don't accept it for bridge building, why do we with code?
Firing Our Top Talent Was The Best Decision Ever | Prime Reacts
23:19
1 Billion Rows Challenge
8:58
ThePrimeTime
Рет қаралды 119 М.
Поветкин заставил себя уважать!
01:00
МИНУС БАЛЛ
Рет қаралды 6 МЛН
The Loneliness of the Mid Level Vimmer | Prime Reacts
9:47
ThePrimeTime
Рет қаралды 66 М.
HTML Templates Instead Of Reactivity | Prime Reacts
12:42
ThePrimeTime
Рет қаралды 113 М.
How much faster has Mojo's dictionary gotten?
7:40
EKB PhD
Рет қаралды 4,2 М.
Being An Efficient Developer | Prime Reacts
22:56
ThePrimeTime
Рет қаралды 155 М.
The 5 Stages of Vim
8:12
ThePrimeTime
Рет қаралды 94 М.
Amazon Says Return To Office Or Get Fired
59:33
ThePrimeTime
Рет қаралды 187 М.
I Solved 1583 Leetcode Questions  Here's What I Learned
20:37
ThePrimeTime
Рет қаралды 650 М.
Everything Breaks NPM
10:49
ThePrimeTime
Рет қаралды 76 М.
The harsh reality of good software
27:28
ThePrimeTime
Рет қаралды 388 М.
Поветкин заставил себя уважать!
01:00
МИНУС БАЛЛ
Рет қаралды 6 МЛН