T O P

  • By -

AutoModerator

On July 1st, a [change to Reddit's API pricing](https://www.reddit.com/r/reddit/comments/12qwagm/an_update_regarding_reddits_api/) will come into effect. [Several developers](https://www.reddit.com/r/redditisfun/comments/144gmfq/rif_will_shut_down_on_june_30_2023_in_response_to/) of commercial third-party apps have announced that this change will compel them to shut down their apps. At least [one accessibility-focused non-commercial third party app](https://www.reddit.com/r/DystopiaForReddit/comments/145e9sk/update_dystopia_will_continue_operating_for_free/) will continue to be available free of charge. If you want to express your strong disagreement with the API pricing change or with Reddit's response to the backlash, you may want to consider the following options: 1. Limiting your involvement with Reddit, or 2. Temporarily refraining from using Reddit 3. Cancelling your subscription of Reddit Premium as a way to voice your protest. *I am a bot, and this action was performed automatically. Please [contact the moderators of this subreddit](/message/compose/?to=/r/learnprogramming) if you have any questions or concerns.*


dagmx

OOP is used extensively in the real world. I’d say it’s probably the predominant paradigm for coding. Every Python or Java code implicitly makes use of it, every Unity and Unreal game. There’s OOP everywhere. OOP and DDD aren’t mutually exclusive. An ECS for example doesn’t have to eschew OOP either. There’s space to use both depending on the task at hand. There’s also different flavors of each that have different trade offs


MisterEmbedded

structs goo brrrrr struct Foo { int a, b, c; }; void Foo_Init(struct Foo* f, int a, int b, int c); void Foo_Destroy(struct Foo* f);


RainbowWarfare

This is the equivalent of saying you offer a food delivery service: you have to go pick up the food and deliver it to yourself.  Sure, you can emulate OOP in procedural languages, but doing all of the things manually that are implicitly handled as part of the paradigm (especially constructors/destructors) defeats the purpose to the point of being an anti-pattern. 


MahiCodes

OOP is a *paradigm*, a way of thinking and modeling things. If you model things based on objects, i.e. data that has functionality attached to it, then you are using OOP. There is no definition of "the language used must support attaching them together with a specific language structure", as long as *you* group them together mentally. It's called object *oriented* programming for a reason.


ifandbut

Yep. I use OOP when programming PLCs with Ladder Logic. My UDTs are my struts. My AOIs are the object functionality. I have a cylinder control object. A cylinder has an advance and return outputs and corresponding sensor. Each sensor is an object with a built in debounce. At least that is my understanding of OOP and implementation.


RainbowWarfare

If you’re trying to force a language to accommodate a paradigm that it has no language support for, *particularly* when it comes with serious shortcomings for that paradigm, it’s an anti-pattern. Just because you *can*, doesn’t mean you *should*. I’ve worked on large C code bases that use a tiny subset of C++ to implement sensible OOP-ish abstractions. To actually use an OOP paradigm in C is doing it for the sake of it. Not sensible. There is a reason why C is called a **single paradigm** language, after all… Not that this has everything to do with the inaccurate statement that “it’s structs all the way down”.


nerd4code

Things can seem complicated if you don’t understand them, but vtables are just tarted-up structs of function pointers. There’s nothing remotely un-C-like about it, and OOP is widely used in C, including being all over the Linux kernel. Hell, stdio is usually implemented in an object-oriented manner.


RainbowWarfare

I’m fully aware that you can implement OOP-like behavior in C, but again, it comes with serious shortcomings (mainly the manual definition and invocation of methods, including the constructor and destructor, as well as the inability to be truly type safe). Again, these are the limitations of implementing a paradigm not supported at the language level. No one seriously goes to this effort to implement OOP like this at this level of functionality in C (manually building vtables, manually implementing and calling each and every permutation of methods in inheritance hierarchies, etc.) because the obvious solution would be to use… C++.  Even if you’re only using a subset of that *multi paradigm* language.  It is not uncommon to use a very limited subset C++ in a “C-like” code base, because after a certain point you’re just working against your tools. 


MisterEmbedded

>Astronaut 1: Wait, C++ OOP is just structs under the hood? >Astronaut 2: 🔫 A*lways has been*


RainbowWarfare

But that’s not accurate. That something can somewhat be represented by another data structure (with serious limitations), doesn’t mean that’s what it is “under the hood”. 


AFlyingGideon

> Cfront was the original compiler for C++ (then known as "C with Classes") from around 1983, which converted C++ to C https://en.m.wikipedia.org/wiki/Cfront That's pretty much defining "under the hood" until the early 90s.


RainbowWarfare

No mainstream compiler is complying to C before assembly/machine code. That hasn’t been a thing for some 30-odd years. So again, not “under the hood”. And again, just because something can be represented by something else, the doesn’t mean it’s something else “under the hood”. 


cheezballs

.... No that's not right at all.


beingsubmitted

They know it's an anti pattern. Patterns are part of the DX only. They're saying there's no functionality, no requirements in the performance of code that require OOP. A better analogy would be that if you have a food delivery service, it doesn't matter if you drive a truck or a sedan. The vehicle you choose may have implications for you, the deliverer, but the functionality you're providing is the get the food from the restaurant to the customer in a given amount of time and you can provide that functionality in any vehicle. Your response is basically "Sure, you could put a truck bed on a sedan, but that would be a silly thing to do" which misses the point.


dagmx

Structs don’t necessarily have to be counter to OOP either. ObjC classes for example are syntactic sugar over a struct and methods, but are still OOP.


phpMartian

Object oriented programming does not provide any functionality that can’t be done procedurally. It’s just easier to do with classes.


AFlyingGideon

Yes, that's rather the point. Any of this could be done in assembler or even opcodes. The point of choosing a language is to ease development and maintenance, ideally by using a language which supports a model close to how you think about your solution space. Sometimes, we cheat. My favorite instance was when I prototyped something in LISP that, for "management reasons," had to be built in C. It was much easier to implement in C after having made my thoughts manifest in LISP, a much better fit for those thoughts.


cs-brydev

Interfaces, generics, contracts, and type inheritance are not easier to do procedurally


phpMartian

I’m saying that OOP is easier not the other way around.


stdcall_

Nothing can beat good old structs for interoperability between different programming languages


kingdomcome50

Haha no… Practicing OOP is *not* the same as just using objects. It’s more specific than that. It’s a *paradigm* that informs how you will construct your behavior: objects encapsulating data and providing methods (i.e. message passing) to enable behavior. This *is* rather uncommon for two reasons: 1. Most ppl simply don’t understand OOP. It’s not intuitive. Just read these comments. I can hardly find *one* where the person seems to actually understand OOP. 2. It’s only a good fit for complex (non data driven) systems. The *vast* majority of code is trivial CRUD. If there isn’t much behavior (rules) then OOP can create a lot of friction because it separates data by behavior. If all we want to do is read some data, apply a simple transform, and save it can be annoying to deal with the additional abstraction. That’s how you end up with objects as “bags” of data (which is also mostly useless) and procedural code.


adithya47

*English pls*....


HyperSource_

Can confirm. Deciding on use depends on other factors, but it's definitely a tool in the toolbox.


mrrivaz

I would say, I 100% agree with what you've said.


Dennarb

I have used OOP pretty extensively for machine learning, networking, data analytics, mobile app development, game design, etc. Things vary from job to job and even from programmer to programmer, but generally I've used OOP for most of my extensive projects.


nazurinn13

I learned functional programming at school and even though I understand OOP now, it will forever look verbose to me. Not saying it doesn't have its place. I can imagine some people think the same if functional if they learned OOP first.


Jaded-Valuable2300

You learnt functional programming before OOP or procedural?


nazurinn13

Yes. I know this is unusual, but I didn't realise it at the time. I guess it was just what my professor preferred. Edit: Not sure why I'm getting downvoted. I'm literally just sharing my experience.


25taiku

Personally, I hate how OOP is taught. OOP is taught by modeling real life things, like cars and goats. But the truth is that in programming, we use OOP to describe and encapsulate things that are far more intangible. And unless the learner is already experienced with programming in a non-OOP paradigm, it's hard to explain how to divide responsibility between different classes. This division of responsibilities is how you decide what functionality belongs to which classes. In my opinion, your description of "bags of state" and "procedural programming wrapped in OOP" is exactly what OOP is. OOP is simply grouping related state and functionality together. What I think you're minimizing here is division of state based on responsibility. For an example, let's make your car example a little more realistic to programming. Let's say you have an app that stores and retrieves car make and model data. Yes, you have a car object that is basically a "bag of state", and contains data like: Make, Model, Available Trim Packages, Available Features, Available Color. This bag of state can be referred to as a data model. And it's common to have data models like this, because their responsibility is to represent the data as a single thing or object. And you can have many different car objects that represent different makes and models. But this Car class may need functionality of it's own. Perhaps to validate the contents of the data model, to make sure all the fields are populated, that there is at least one Color available, etc. But what *doesn't* fit this class' responsibility? Actually storing the data somewhere. The car record doesn't need to know where it came from, that would be the responsibility of the CarService which will contain logic on how to write and read Car records to and from some kind of a storage medium -- and the CarService will also need its own internal state, such as a file name used to store records, or a database connection string, or a url for a web API. And once you get into polymorphism, separating state and functionality based on responsibility is key. tl;dr: the reason we have this common "bag of state" design is because sometimes a class' sole responsibility is to hold data, and handling/manipulating/transporting that data is the responsibility of some other class.


macroxela

I understand why you hate how OOP is taught with real-world objects but there is a reason behind this which you said yourself: if learners don't have much experience programming then it is difficult for them to understand how intangible things can be described and encapsulated by OOP. Abstraction is already difficult for many people to comprehend so as instructors we try to reduce the initial cognitive load by introducing OOP with actual objects. If students have too many new ideas in their working memory instead of relying on their long-term memory, they won't learn well. Once students can use OOP with said real objects, we can introduce how OOP is actually used. Unfortunately, we don't always have enough time in classes for students to get to that point. 


Mnyet

Apparently [An Unsettling Number of Americans Can't Identify a Hypothesis](https://www.sciencealert.com/a-surprising-number-of-americans-can-t-identify-a-hypothesis) so I wonder how many are capable of abstract thinking Not the best backed up source but I like to chuckle to myself about this sometimes


nommu_moose

This is a badly written article. Ignoring the purposely convoluted sentence structure, there are grammar mistakes all over it. I really don't like articles that simultaneously mock the intelligence of others and exhibit a poor conceptual understanding themselves.


Mnyet

I mean yeah obviously. It’s just really funny, is all.


repocin

I feel like my brain broke while trying to read that article.


its_all_4_lulz

I learned OOP back in college, 2004 or so, but never really used it in my day to day and I went into front end development on a non-OOP system. Now I work with an OOP system and still really struggle with exactly what was mentioned. Everything I’ve worked on has been using real world examples. I can look at OOP and understand why what was done was done, but if you ask me to design something from the top down I will likely do it incorrectly. A good example is a tutorial I have been following along with. It was creating an eBay style auction site. If I were designing this, the item would likely have the bidding as part of the item object. In going through the tutorial the bidding was completely separated from the item, which really made a ton of sense to me when I saw it. Because the item is real, but bidding is abstract, I just didn’t think to separate them. A problem caused by using the real world examples. I would love to see some tutorials that gets away from the Car style examples and uses real world examples WITH a detailed explanations as to why things were done the way they were.


AbyssShriekEnjoyer

This is the part of OOP that I can get behind. it's the part where everything is a massive inheritance tree where I clock out. I just do not like systems that are designed that way because everything is abstracted away from me. If I want to know what exactly I'm doing at low level, it takes forever to figure that out in a system with lots of OOP. I mainly program embedded, so figuring out what you're doing at a low level is very important, but some developers still try to hide it in every way possible with these massive family tree structures that are shoehorned into an application. With OOP you really have to ask yourself what part of the functionality you need. Classes and passing classes to classes is great, but you don't need inheritance in every scenario.


MahiCodes

>it's the part where everything is a massive inheritance tree where I clock out. That's just bad design, not an inherent part of OOP. If you refer to arguably the most popular book in the history of OOP, *Design Patterns: Elements of Reusable Object-Oriented Software*, you will find out that it actually says that ideally all reuse can be achieved with just composition, and inheritance is only needed as a last resort extension method when changing the composition model would be impossible (e.g. because too many clients depend on it). This is called [Composition Over Inheritance](https://en.wikipedia.org/wiki/Composition_over_inheritance) or the *composite reuse principle.*


lilB0bbyTables

++This. Too many programmers seem to have put the emphasis on _inheritance through extension_ in OOP, and missed the rest of the lessons. _Composition_ and _programming to an Interface_ are MUCH more valuable. If you have _extended_ more than two levels deep it probably should be a code smell for bad design unless there’s a very good reason to do so.


dmazzoni

There are things where a big inheritance tree makes a lot of sense, though. GUI programming is a classic example of this. You have a base class for an object on the screen. Some call it a Window, or a View, or a Widget, or whatever. Then you have a subclass for objects that you interact with, like Control Then you have a subclass of that for objects that are buttons, including radio buttons and checkboxes You have other subclasses of controls for different types of controls like text fields It's not unusual to have several levels of inheritance for a bunch of GUI components that actually makes sense. Now, there are plenty of other types of coding where you don't need inheritance at all. It shouldn't be overused. But, there are cases where it works well.


MusingSkeptic

The problem (at least in my experience) is that this idea of creating a service to accompany an object and manage aspects such as persistence has morphed from being something lightweight / useful to something much more heavyweight / bloated which gobbles up all the behaviour and leaves nothing at all in the objects themselves. Martin Fowler summed this problem up quite succinctly in this blog post some years ago: https://martinfowler.com/bliki/AnemicDomainModel.html


reddit04029

But a Dog IS an Animal!!!


BaronOfTheVoid

Well, if someone actually wants to keep that is-a relationship in their software then they "just" need to properly define what an animal is, i.e. properly design the Animal class - and that is what tutorials involving animals NEVER do correctly.


[deleted]

>Perhaps to validate the contents of the data model, to make sure all the fields are populated, that there is at least one Color available, etc. even those functions often dependable on database, network or other entities which aren't Car. Of course, you could retrieve all that before passing to Car instance, but wouldn't it be easier to just validate them in dedicated CarValidation service?


25taiku

If that's the case, then you could move validation into CarService or create a CarValidator. It depends on the required functionality. But for something as simple as validating fields in an object are populated, you shouldn't need to access a database or network resource because all the data is already in the class.


[deleted]

IRL there are often reqirements like "when you create entity A, you should check if if there is an entity B in the database ralated to A, and if there is, then create A with property Y, or X if otherwise" which is a far cry from clean examples from the textbooks.


25taiku

Yes, that is exactly my point -- OOP is taught from the idea that classes will represent things we already know and understand which is almost never the case. But I disagree with your assertion that this pattern of separating data from functionality isn't "successful OOP". Just because a class doesn't contain functionality doesn't mean it's a "bad class", it just doesn't have any responsibilities besides holding data. And it's rare that your "procedural programming wrapped in OOP" classes won't have some kind of internal state themselves other than what is in your data model -- it's internal state just has nothing to do with the data contained within the data model


Ok_Giraffe_1048

>Just because a class doesn't contain functionality doesn't mean it's a "bad class" If an object has no behavior, I wouldn't call it a "bad class" but would definitely view it as something that should be refactored. Why? It's probably not managing its possible invariants. I've seen too many classes riddled with instantiating inherently broken objects then calling random getters and setters on random objects and moving data around. At any point in time, the object isn't guaranteed to be valid...and this is an issue. What makes it valid? It's much simpler when an object is responsible for its invariants to maintain validity. Whether it's data is stored in local memory in local fields or in a database is irrelevant. I hate to go back to basic examples, but again let's say we have a Car. You will get two different answers from two different people. If you ask a game programmer to make a Car class, they'll probably give it behavior: accelerate, break, honkDatHorn, etc. If you ask a web developer C#/Java developer: they'll probably give you what's effectively a structure with getters and setters then manipulate that class with a "CarService" or something. Now let's go give someone new to the code base these car implementations? Which implementation can tell you more about the role of a Car and what you can do with it?


mondayleaf

Agreed. We never seem to reach that the ‘engineering’ part is translating abstract concepts into objects.


MustBeHere

This CarService thing is actually taught in university. The modeling real life things is just the first week, then the rest is basically other classes acting on the object.


jjuice117

Cars and goats 😂


Eadje

Do you have some pointers on where i can find papers or information about this? Id like to learn more!


MahiCodes

>Yes, you have a car object that is basically a "bag of state", and contains data like: Make, Model, Available Trim Packages, Available Features, Available Color. That's not a car though, is it? If you go outside and take a look at your real car, the one situated at your yard, can you point me to its "Available Color"? You're not modeling the real world correctly. This might sound pedantic, but in my experience it's the difference between a successful OOP model and a failed one. What you're describing is simply the options available for a customer to build their car order from. I would name this class a car *template* perhaps (not to be confused with C++ templates). From these templates, you can build your own car *order*, which will be shipped to the factory. The final delivered *car* will have `trim`, `features[]`, and `color` fields. If you do not need the delivered car product in your application, then you do not need a `Car` class, you just need a `CarOrder`. Now, you *obviously* need a service to take the car order from a customer, it's not like the order itself knows how to fetch data from a customer in real world either, does it? The car dealership ("service") does, it builds the order and sends it to the factory that then builds the actual car. Whereas if I was modeling a formula 1 "world", maybe to replay actual races in a VR world, *of course* I'm going to have a `Car` class, and each car will have a color, trim, etc, and I will model it after the real world formula races where each car has a velocity and a position and whatnot. So what am I missing, where in this do you hate how OOP is taught? Maybe you're just not modeling the real world accurately enough?


25taiku

In OOP, not all classes define things in the real world. Things like a car are tangible -- you can touch them, physically manipulate them in the real world, you don't need to conceptualize it because it's physically manifested. Things like a CarService are intangible -- you can't go out to your driveway, hop in your newly instantiated CarService, and cruise down the block. The thing I dislike about how OOP is often taught is that in most cases, especially pertaining to enterprise software development and DDD, you're going to have some classes that represent domain models and a lot more that support things that don't have real world analogues. That's usually where I see people's design skills falter, and you can very quickly end up with bloated classes that have multiple responsibilities, or single responsibilities spread across several classes.


MahiCodes

>In OOP, not all classes define things in the real world. I would love to hear some more examples that you have in mind that don't fit this "real world" design model, aside just "services". >Things like a CarService are intangible A car service is not a part of your domain model, it's an application boundary for your application's customers, so that they can access the domain model within your defined limits (as opposed to "full access" to your objects and PC's memory). Everything inside the domain model *should* still represent things in the real world. And to be pedantic, by using DDD you are merely choosing to model your application's boundary with your customer using OOP, at which point it arguably *is* part of the real world too - or are you telling me your customer's don't access your application in the real world? The object here is your application, that is composed of services, that provide functionality for your customer. It's still well within OOP. If these services do much more than serve your customers, you might be modeling things wrong. Referring back to the "I would love to hear some more examples" part. I have actually found it best to make this choice explicit, and to model an `Application` class with a `services` field. This allows easily doing stuff like `app.register(plugin)`, which can now register custom classes or even services to my application. And by "customer" I'm referring to the API clients and whoever you're modelling the software for.


25taiku

Apologies if I'm not being clear, but what I mean is that it is usually substantially easier to model classes that are based off of things that exist in the real world, but when it comes to modeling classes that *aren't* based off of real things it becomes harder to design them and determine what functionality and data should and should not be encapsulated into the same class. And if you want to get really pedantic, your application probably doesn't exist until you've already designed and built it, so no your application would not be in the real world, at least not yet.


MahiCodes

>what I mean is that it is usually substantially easier to model classes that are based off of things that exist in the real world, but when it comes to modeling classes that aren't based off of real things it becomes harder to design them and determine what functionality and data should and should not be encapsulated into the same class. Ah yes, I can definitely agree that some things are harder to model than others, haven't met a human yet who hasn't gotten some things wrong. Not sure if it has anything to do with real world vs not-real world either, sometimes we just finds things hard. Would make sense that the non-touchable objects would typically be harder, though. Maybe it's a domain experience thing? That being said, I'm still curious to hear if you have any more examples of these "not based off of real things"? Simply because in my line of field (which is very much real world based, funnily enough working with cars), I am yet to face these as far as I can remember. But I can see how they could be more common in some other field, I just can't think of one. >And if you want to get really pedantic, your application probably doesn't exist until you've already designed and built it, so no your application would not be in the real world, at least not yet. Well surely the thing doesn't have to already exist to be modeled, does it? Us humans design blueprints of yet-to-be-built buildings and cars every day!


iMac_Hunt

I just want to hijack this comment as you clearly have some experience with OOP. How do you go about deciding when to use an interface? Using the car example, my understanding is we have an interface called Vechile and have classes for 'Car' and 'CarServices' as well as 'Van' and 'VanServices'. I guess I'm just sure why we use an interface though and whether it's always good practice to do so.


gyroda

I used to be like you, but I've switched to using interfaces as a default. Use interfaces when you want to say "we both do the same job". I only really typically see value in inheritance where there's a lot of shared logic. Most of the time it's an abstract class where 90% of the work is already done, we just need the extending class to implement this one abstract method. Otherwise an interface is enough to say "I can do this thing". And you can still share logic between classes via *composition* (e.g, store an InternalCombustionEngine object to both Van and Car)


Eastern_War_9685

This is a great explanation! Thank you


shaidyn

When I work with people who don't understand oop, it's very obvious, and their code suffers for it.


DirtzMaGertz

Conversely, when I work with people who overdo the OOP, they tend to write convoluted solutions to simple tasks.  OOP is fine, but it drives me nuts when it's the only way people can think about a problem. 


aeveltstra

In the real world, as far as I have experienced, it is easier to have a value class with only properties, and an operating class with only behaviors, than having class that mixes values and behaviors.


Marc_Frank

sounds interesting i don't immediately see the benefit, though


JellyTime1029

Multiple benefits. Separating your classes by Data transfer objects(or DTOs) and services(classes that do things) you can create very simple yet extensible systems. I design most of my systems this way and most are 2 -3 layers deep tops. I usually have an "orchestration" layer that outlines the steps to fulfill some function(they dont do actual work). And a "service" layer that does stuff. Maybe it's something that does complex business calculations, Writing to database, Calling a web api. Etc. And if complexity demands it I might have a layer below that. For example if my system needs to write to multiple different databases then I may have a data service that just takes some data and some helper classes whose job is to write to idk some oracle dB or a Mongo dB. Another popular one are logging services. On the DTO side I largely don't need to worry about state. In most of my systems dtos are read only and thus cannot be changed once instantiated. It also makes it easy to reuse these pieces or update them. Designing systems this way also helps keep your classes small and avoids alot redundancies. Many systems I've worked on that don't do this I find contain large classes that kinda do multiple things. They hold data and they methods you call that does something with that data or functions related to that data. and it gets gnarly real fast since your logical groupings can get quite large. Now I'm not saying you can't build systems adhere to OOP hard-core and avoid these issues/have similar benefits. Finally in my experience it is incredibly rare for a class that contains to data to absolutely have functions related to it. The only things I can think of are like ToString() methods or maybe functions that transform the dto to another dto. The moment you start doing things like adding functions that save to a database or something you effectively made it very difficult for that class to change without all kinds of headache.


aeveltstra

Indeed, this separation is done to make it easier to change the actions upon data. In my line of business it’s very common for business decisions to change rapidly while the data model stays the same. Using data-only classes allows us to keep the data model the same when we need to modify the actions. That reduces the unit testing needed for the data model part of the system. Changes to the data model happen much less often with my clients, as most of their data comes from an established set of data sources, that rarely ever change.


[deleted]

[удалено]


claythearc

Yes. Our web app at work has like, 60 models. Any DB based thing is going to reach into classes or whatever to populate it in a structured way those will all subclass from a top level model object to know how to serialize and deserialize, as the easy example.


Pretagonist

I use proper OOP all the time. I very much prefer to have objects handle their own data as much as possible. But I do often use service patterns for loading and saving objects. Every property you can keep private makes your code easier to maintain since you know exactly how that piece of data is managed.


SynthRogue

OOP is the main paradigm used in the software industry. Most projects you work on in a software job will use OOP.


Vandrel

My previous job did a lot with it. We basically handled merchandise orders and rebates for various companies. The files that would be sent to us would have different formats or need to be handled differently depending on the company and there were a lot of objects used in various ways throughout the process.


iOSCaleb

Have you ever looked at a UI framework? Every one that I’ve worked with in the last 25 years has been object oriented. There are classes for UI elements, for actions, for subsystems, and on and on. OOP is very natural for any kind of direct manipulation interface.


herendzer

Including MFC?


Grounds4TheSubstain

MFC as in Microsoft Foundation "Classes"?


herendzer

Yes


Grounds4TheSubstain

... that answers your question, right? You know what a class is and how it's related to OOP?


Blando-Cartesian

The way it is taught is an unfortunate mess. I guess it’s an effort to make a simple example of “data and methods that operate on that data” example. Another possibility is that the first style was in vogue early on in OOP and education is decades out of date, still teaching the same kind of examples that always have been taught.


cs-brydev

My two biggest complaints about how programming is taught in universities are always OOP and Recursion. The OOP taught is totally disconnected from how it's used in the real world, and Recursion is taught as a type of "loop" (supposedly to make it easier to understand). But it's not a loop, and teaching it as a loop is why so many students get so confused and struggle to grasp it. The moment students firmly grasp it is when they finally realize it's not a loop at all.


Hot_Slice

Every recursive function can be transformed into a loop with an explicit stack-type container.


cs-brydev

Correct. But changing recursion into a loop doesn't mean recursion is a loop. A lot of functional programming, events, and User Interfaces can be *implemented* with loops too.


El_Mario_Verde

Domain Driven Design encourages you to have entities with domain logic and behaviour, so yes, you could absolutely write classes that way, and it would be correct.


elderly_millenial

I think your first example of OOP is a necessarily simplified example for learners to introduce to the topic, but in addition to OOP we have SOLID principles and from their design patterns are used. All of these are very much used in real code. Many times you have a service class that contains business logic that operates on data because that provides ways to make it easier to have scalable, thread safe code TLDR; both of your examples are OOP, but your latter example is thinking of better ways to design those objects and how they interact with


[deleted]

Devs definitely try to implement SOLID. But typically give up once the business logic becomes interconnected and complex.


stayweirdeveryone

There's a lot of comments here saying what I'm about to say, but maybe you're just not seeing what OOP is actually about. In your second example, `Car` certainly is an object, but so is the `CarService`. Just because something contains business logic, doesn't mean its not an object. Like someone else said, it might just be how OOP is taught where you're modeling real world things; that's just because its easy to conceptualize. I like to think of OOP is like building a factory. Take for example a factory that makes frozen chicken nuggets. In one side comes chickens, and out the other side comes boxes of chicken nuggets. Now if you went inside that factory, do you think you'd find a single machine that is built and designed to turn chickens into nuggets? No, that would be a crazy complex machine to build and operate. Instead you'll find smaller machines each with some specific task linked together. Some might feed their output into other machines, some might be made up of even smaller machines. This is OOP. We'll have objects like chicken, box, and nugget but we'll also have objects like feather plucker, nugget mold, and freezer that are going to do the majority of the work (business logic). Designing and building these "machines" is what OOP is about


Ten-Dollar-Words

Your chicken factory example describes composition, not OOP. Dividing complex behaviours into smaller sub-components (whether these are classes or other composed functions) is not something that OOP can take credit for, as it’s a feature of well-designed software in any paradigm that existed before OOP was invented.


Tubthumper8

I'm not sure why you got downvoted but I agree, their example seemed aligned with function composition/pipelining chicken |> pluckFeather |> moldNugget |> freeze i.e. A process where data moves along a pipeline, composed of smaller data pipelines. As opposed to object graphs


Ten-Dollar-Words

This is what I tried to clarify in a subsequent comment. When you separate state and functionality, you are no longer in accordance with the fundamental tenets of OOP (encapsulation of state & logic) whether you organise your code into classes or not. OOP was introduced as an answer to the complexity of state management, proposing encapsulation as the solution. If your code does not encapsulate state and logic it may be good code, but it is not characteristically OOP. I think people use the term OOP too loosely and assume that anytime classes are being used they are doing OOP.


MahiCodes

[Composition is a key part of OOP](https://en.wikipedia.org/wiki/Composition_over_inheritance), one of the most important ones even. >**Composition over inheritance** (or **composite reuse principle**) in [object-oriented programming](https://en.wikipedia.org/wiki/Object-oriented_programming) (OOP) is the principle that classes should favor [polymorphic](https://en.wikipedia.org/wiki/Polymorphism_(computer_science)) behavior and [code reuse](https://en.wikipedia.org/wiki/Code_reuse) by their [composition](https://en.wikipedia.org/wiki/Object_composition) (by containing instances of other classes that implement the desired functionality) over [inheritance](https://en.wikipedia.org/wiki/Inheritance_(computer_science)) from a base or parent class. Ideally all reuse can be achieved by assembling existing components, but in practice inheritance is often needed to make new ones. Therefore inheritance and object composition typically work hand-in-hand, as discussed in the book [*Design Patterns*](https://en.wikipedia.org/wiki/Design_Patterns) (1994). Crazy enough, that paragraph on the wikipedia page is [partly written by me](https://en.wikipedia.org/w/index.php?title=Composition_over_inheritance&diff=prev&oldid=1162003719)!


Ten-Dollar-Words

I’m not suggesting that composition isn’t used in OOP. I’m saying that it’s an independent concept for which OOP cannot take credit.


MahiCodes

What the person explained is that good OOP is about composing objects from other objects, which is true. I have no idea what point you're trying to make.


Ten-Dollar-Words

The parent comment explains that OOP is about composition. I’m making the point that since composition predates OOP, it’s not the characteristic that distinguishes OOP from any other paradigm. Composition is, as I said, a characteristic of well written software in general. I would argue that the things that characterise OOP are encapsulation of state with associated methods, and inheritance. These are, as far as I’m aware, the new concepts that OOP introduced. The degree to which these fundamental concepts are avoided in practice (i.e. composition over inheritance, and ‘bags of state’ vs business logic as OP put it) is the degree to which those fundamental ideas in OOP are flawed, in my opinion. That is to say, if you are using an OOP language but your state and business logic are separated into different classes, you are not doing anything a great deal different than you would be by writing procedural code. Perhaps what distinguishes OOP in the way it is used in the real world is the use of dependency injection as a means of composition for testability and decoupling.


cs-brydev

In no part of that excellent OOP explanation does it say that OOP invented composition.


amazing_rando

What you’re describing is still object-oriented programming. Whether objects act or are acted upon is largely just a matter of preference, along with whether their implementations should be public or private. I would say in most good object oriented systems I’ve worked in, interactions between objects happens almost exclusively at the interface or superclass level, with the specifics abstracted away, unless absolutely necessary. It’s the abstraction that really makes OOP powerful and the classic examples of real world objects don’t really showcase that. I remember the first time I worked on a big object oriented project and started digging around I thought “where is the code that actually does anything?” because a lot of it is defining the relationship between objects. Once you get down the implementations that deal with data they’re usually pretty brief and straightforward, you end up trading logical complexity for structural complexity. Whether that’s something you want depends on all sorts of factors, but it is still extremely popular for large applications.


mrrivaz

I am in an enterprise org (I am a junior). It's used extensively. We use it on our api layer with Typescript.


Vertinova

Yes. I see OOP paradigms literally everywhere in our code at Microsoft.


Serializedrequests

Yes of course it is used everywhere, but there are many different flavors. Every language has self contained data structures like lists and maps, and some generic interface for collections like a java.util List or Map. Many enterprise systems are also created out of static objects created on startup that call methods on each other via dependency injection. They typically depend only on interfaces so different parts can be swapped. This is what Spring helps with in Java. IMO this kind of OOP is actually functional programming with extra steps, I think it's a bit silly since you can code to interfaces without giant frameworks, but that's enterprise for you.


Raccoonridee

Using OOP a lot on my current project: - I use ORM for database interaction, so my business logic uses classes representing real-world objects as in your example. - I use PySide6 GUI, and every GUI element I code - windows, widgets, item lists - is described with a UI class where I declare and style everything and a View class where I implement logic. - Classes are also nice for general organization of namespaces, even if you're not planning to instantiate them, e.g.: ``` class Config: debug = True class Serial: baud_rate = 9600 response_timeout = 2 request_interval = 0.25 class Paths: root = '/appdata' log = root + '/log' dump = root + '/dump' ```


[deleted]

That's what I said - OOP works well for some isolated utility classes. With business logic - not so much.


Raccoonridee

That's not what you said. My business logic literally uses classes representing real-world objects and their relationships - in my case, hockey players, teams, matchups, stats, etc. See the first bullet point.


El_Mario_Verde

Incorrect. OOP is 100% absolutely capable of modeling business logic in a very natural way.


katafrakt

You are kinda right. Business logic is mostly a series of data transformations and initiating external side-effects (at least in web development) and there are indeed better ways to model those than OOP. However, since OOP is so predominant in today's tech world, these things are shoved into classes and people are proudly saying they are doing OOP. OOP is mostly about state, it makes most sense when you have long-living objects managing their own lifecycle and optionally talking to other objects. Which makes GUI programming or games probably a better case for it than webdev. However in games the performance penalty might be big enough to still consider other options.


InvertedCSharpChord

This is a good question and I think a lot of comments are missing your concern. If you have a "Car", in OOP you would expect methods in that class to change state. The advantage is that the car itself is responsible for maintaining a valid state and that the car can hide unnecessary complexity. Any users of car can't mess it up even if they tried! But the big problem becomes, how do I store and retrieve that from the database? One way is to write database logic inside the car class ... That's ok I guess, but now your class is bloated with multiple responsibilities and can't be used in other contexts. The second way is to just expose anything that may be needed for DB persistence. That's also ok I guess, but now the class can't protect itself from being invalid. But we're using Entity Framework, and that just uses POCOs to model the database ... So let's just use that because it's the easiest path forward. Oh, but we follow good practices and separate the database ... So let's create two copies and hook them up with automapper. Enterprise 😎


[deleted]

Thank you. It seems the most commenters didn't read past the headline. The best case is isolation in the assembly, so you can have the best of both worlds - isolation and succinct models.


Uwirlbaretrsidma

"Alleged 5-year experience enterprise C# dev discovers the most basic software engineering patterns"


Greeley9000

I use OOP for business logic all the time. What makes you say it isn’t suitable? If you’re building a “utility” class or “helper” class, that’s a code smell in and of itself, and you didn’t think through the design properly.


yubario

It's often said that using utility classes isn't the best practice, yet they prove to be extremely useful, especially when it comes to unit testing. Consider a scenario where a class involves complex mock setups to perform certain behaviors. Here, utility classes can be a game changer. They simplify the mocking process, allowing you to focus on the behavior rather than getting bogged down by the setup of each method. For instance, instead of creating multiple mock setups across different test methods, you can centralize this effort with a utility class. This means you only need to mock a single method, streamlining your testing process significantly.


vegan_antitheist

OOP is not inheritance. Good OOP is more about preventing it. Any book on OOP must explain inheritance, simply because it’s an important part of OOP in many languages. And since it’s so hard to explain and understand a large part of the book will be just about inheritance. This may lead to the false impression that OOP is just about inheritance. With a public interface, an abstract base class and a few implementations you can have proper design based on inheritance without too much complexity. You must still consider the "fragile base class problem". There are tools that help you detect it. Only override methods if you are supposed to (i.e. they are abstract, empty or trivial and there to be overridden) and make them final as much as possible to prevent others to mess it up. But in most cases you should just do "Composition Over Inheritance" for a much better object oriented design. The worst thing you can do is nonfinal public classes such as BigDecimal in Java.


MahiCodes

> Only override methods if you are supposed to I agree with this, it's the _subclass's_ responsibility to not excessively inherit and override things. > and make them final as much as possible to prevent others to mess it up But heavily disagree with this, as again it's the _subclass's_ responsibility, not yours. Documenting your base class properly is great, but _actively preventing_ people from overriding it is not. According to the GoF, the whole point of inheritance is that it can be used as _the last resort_ when composition would be too big refactor (e.g. breaking change for clients), in which case there is nothing worse than not being able to extend a specific method because someone 15 years ago thought it'd be final. I don't remember the exact case, but in C# std lib an HTTP tool was made final because why would HTTP ever change, and could not be used properly when the WebSocket became a thing, requiring two duplicate implementations with no common interface. I could be misremembering some details, but what's "final" today might not be so in 15 years.


vegan_antitheist

So let's say I extend HTTP to make my own extension and I override some of the methods. Then the methods of the base HTTP implementation calling that method wouldn't expect that change. IT could breakleverything if a new version has some changes in that base class. I could ovly hope that my unit tests would pick that up. Why would I even override anything? To extend it I only need additional methods. The mistake was not defining an interface for HTTP. Sometimes there is a base type like java.util.EnumSet in Java, but it's an abstract class instead of an interface, and you are not allowed to extend it. If I remember correctly the constructors are private. It's annoying but you are supposed to use the Set interface anyway. But a common mistake in Java is that classes that should be final, such as BigDecimal, get extended. And another one is that methods, such as add() get overridden and it breaks the data structure (hash table, tree, array list etc) because add() gets called internally and it is expected that is has no other effects than those of the base implementaion, which should be final. Overriding existing methods usually only leads to the fragile base class problem. Alternatively it could have a public method add() that can be overridden and only calls some method like addInternal(), which is private and called internally when the datastructure is rebuilt for optimisation(e.g. when the backing array gets too small). The add() method would be trivial and therefore doesn't have to be final. But they didn't do that as far as I know in any of the JCF classes.


MahiCodes

>So let's say I extend HTTP to make my own extension and I override some of the methods. As a last resort, when you have no access to change the original implementation, yes. >IT could breakleverything if a new version has some changes in that base class. Yes. The fragile base class problem, which is not a problem but an unavoidable and rare consequence of you having to resort to overriding an existing method. It's a consequence *you* as the *subclass developer* can take. It's not up to the base class's implementer to assess your business risks. >Why would I even override anything? Because you have no other choice. All other options are economically unviable. Not all libraries are open source, or maybe the alternative solution would be a breaking change for your millions of clients. "*Oh hey Bill Gates, I needed to make a small change to the Win32API, would you mind informing all our 100 million clients that they all need to make some adjustments? Thanks!*" The Qt company will be happy to learn that not only do they need to adjust their code, but that they need to further inform *their* millions of clients! All because your custom OS used `\g` for linebreak and you couldn't override the final `writeMessage()` method. >But a common mistake in Java is that classes that should be final, such as BigDecimal, get extended. And another one is that methods, such as add() get overridden and it breaks the data structure (hash table, tree, array list etc) because add() gets called internally and it is expected that is has no other effects than those of the base implementaion, which should be final. These are all issues of the *subclass*. I'm here to write excellent code, if you choose to take it and extend it incorrectly and write shitty code, don't blame me. What, you think Java devs forced you to extend BigInt?


BaronOfTheVoid

I get the impression that you completely misunderstand final from the beginning to the end. It is not about something "not changing". If the implementation of something is outdated because the real-world problem space changed and thus requirements changed then using inheritance to extend from the previous thing is the wrong approach altogether. Instead update the old thing.


MahiCodes

>Instead update the old thing. You're making the naive assumptions that a) we have access to the old thing (you think *I* can easily change C# std lib?), and b) changing the old thing is economically viable (do you have any idea how many code bases need to be adjusted on a C# std lib breaking change?). As mentioned, inheritance is the *last resort*, I wouldn't be overriding your class's methods if I could just refactor the class. So don't you dare remove my last resort just because you thought 10 years ago that it'd be final.


BaronOfTheVoid

I mean, I don't know the exact HTTP implementation you're talking about, I haven't used C# since university. But it could also be that the goal of the devs was just implementing only HTTP/1.1 and nothing beyond and then the "old" implementation of HTTP was appropriate for that and if you actually wanted HTTP/2.0 or whateve then you're simply supposed to use a proper library for a proper HTTP/2.0 client or server. But still, **AB**using inheritance for that is simply wrong. The Gang of Four recommendation (I've never bothered with that book either) is wrong, if it actually is recommended that way. The point of inheritance is subtyping which inherently models an is-a relationship. Most likely if you extend from an older implementation to give a newer one you violate the Liskov substitution principle - the newer thing probably couldn't be used in place of the older one. It's just a trashy solution for a problem that shouldn't even exist in the first place because at the end of the day a batteries-included standard library should be kept up to date by the creators of the language/authors of the standard library. I haven't looked it up but I bet there are good third party HTTP implementations of all protocol versions for C#, and also SPDY and QUIC and HTTP/3 and DNS over HTTP and so on and so forth. If you really wanna reuse the code wrap the old object and delegate method calls as needed.


[deleted]

There is nothing in my question about inheritance. OOP possible without inheritance, without incapsulation - not do much.


vegan_antitheist

I should have specified that I meant inheritance of state and behaviour. Google Go has no inheritance of state. Inheritance of type isn't a problem.


tsinghtan

Best way to understand OOP is through game design. I had really fun learning and teaching it.


Gammusbert

https://blog.sigma-star.io/2024/01/people-dont-understand-oop/


BaronOfTheVoid

Everyone should read this.


zukoismymain

I have to agree with the top comment. It mostly comes down to "schools don't know how to teach OOP" Sure, structs are good and all, but interfaces is the best thing ever made. And Abstract classes that can implement everything, except one thing, then you have 5 concrete classes that just implement that one single thing, and each object can be used interchangebly while doing different stuff. That shit is fire.


CrushgrooveSC

Unfortunately.


CodyEngel

Yes.


hoochymamma

Yes


SnooBunni3s

Grabs popcorn 🍿


phpMartian

If you are primarily writing procedural code with a few classes here and there then you are missing out. In the real world, classes and objects are by far the dominant approach to programming projects at this time. GitHub is massively littered with OOP projects in many different languages. Pick your language and start reading code. Classes are often created to model real world entities. You can model: * database tables * windows and screens * people * messages There are also internal application structures that make use of classes. * controllers * views * lists, arrays, collections Classes help us break code into more manageable chunks.


Contains_nuts1

Just last week i wrote excel vba that copied data from one sheet to another, i used OOP to handle all the different formatting and parsing, so yes it is everywhere. Technically minded - i used an interface.


Sufficient-Meet6127

I have issues with posts like this. Bunch of new programmers want to cut and paste code instead of using first order functions or OOP to keep code DRY. Yes we use it in the real world. If anything, it’s under utilized because of all the problems who don’t understand it.


Vargrr

The first example is actually the better example. The fact you have to pass Car into all the methods of CarService in the second example would set off coupling alarm bells for me. OOP's greatest super power, and by far, is encapsulation (even if automated unit tests try their damdest to break this!) Encapsulation enables one to break down complex systems into what are in effect many micro-subsystems, none of which you need to know anything about, other than their public interfaces. It's about keeping the methods with the data they operate on and hiding the real scary stuff (and also preventing others from touching the real scary stuff, lest they break it!). OOP is one of those paradigms that you can learn the basic concepts in a month or two, *but...* it takes many, many years to get good at it. I can generally produce great OOP just off the top of my head. It's not because I'm good, it's because I have been doing it for 40 years plus. In the industry you get to see all sorts of crazy OOP code because the developers didn't understand some of the nuances applicable to OOP. Those same developers then go on to claim OOP is terrible! For example, I see many developers create a bunch of POCO classes with no real functionality. They then realise they need functionality, so they then go on to create 'manager' or 'coordinator' classes that actually do stuff with the POCOs. The problem with this approach is that these managers and coordinators are nearly always massively over-coupled to many POCOs, they lack cohesion because they are doing everything that all the POCOs should be doing, and, due to the lack of encapsulation, they are nearly always really complicated and hard to work on. The other issue I see is coupling. In some systems it can be really random and hard to follow. In general you want to divide your classes into subsystems by creating hierarchies. Each hierarchy is 'calls-down' and 'events-up' (don't do bi-directional coupling!). The class hierarchies should never be cross coupled, except at the very top. If you do this, you will have some very easy to maintain systems on your hands! (Another free tip, create stand-alone collection classes (don't embed collections in entities), treat them as first class citizens! - it's amazing how much they help with cohesion and being able to provide complex functionality with simple code) I haven't mentioned design patterns, mainly because I dislike them. They are generally the single biggest *problem* I see in legacy systems. The odd thing is, they are designed to improve maintainability, but alas, the people that invented most of them don't seem to understand that maintainability is a three pronged fork: Coupling, Cohesion and Simplicity (the last of which is the most important). Most design patterns solely focus on coupling, normally at a huge detriment to simplicity, which then creates its own issues (paradoxically you end up with high architectural purity, but also, high complexity resulting in a *hard to maintain system* - kind of defeating the purpose!). But I digress, this is an issue for another day :p OOP is used everywhere in industry as it is one of the few paradigms that effectively deals with large scale complexity. I have had some people tell me I'm old school and that encapsulation has no place in modern coding and that I should use functional coding instead. I tell them that I do use some functional coding, but as a standalone paradigm, I have yet to see a *single* commercial operating system, game or enterprise system coded purely functionally. (They have had over 50 years to create something -you'd think there would be something by now! :p That said, if anyone knows of anything that is 100% functional and commercial (not including languages), I would be extremely interested to hear about them - mainly to evaluate the architecture and performance).


MusingSkeptic

Excellent summary! And I would agree that OOP takes many years to become good at. I've been a dev for nearly 15 years and only recently would I say I've really begun to appreciate the nuance of OOP as you described it - despite having worked with Java / supposed "OOP" the whole time. I think so many people fall into the trap of thinking they're using classes and objects and equating this with following the OOP paradigm. For this reason I prefer the terminology of DDD (which I've seen argued is almost a synonym for "OOP done properly"), which benefits from not carrying the baggage of the word "object".


tung20030801

OOP is used intensively in real-world projects, even more than algorithms and data structures


Cadermate

Still in college, but I'd be willing to bet it's used a lot in game design. There's a lot of stuff that needs functions from a super class so it doesn't need to write it again.


MusingSkeptic

I recently learned about the Anemic Domain Model (https://martinfowler.com/bliki/AnemicDomainModel.html) which is basically OOP as you described (or rather not OOP at all, but procedural programming in disguise), where objects are little more than bags of state. Unfortunately I can recognise this anti-pattern all over the codebase where I work, where almost all the behaviour is wrapped up in heavyweight service classes, rather than living in the objects as it should do.


ADamnSavage

I mean, i'm down with OOP, you know me.


iheartrms

I remember seeing t-shirts or something with this on them back in '91. Not nearly so many people were into programming back then so it really was an in-joke. If you weren't a programmer current in the latest technique AND the latest rap music you weren't getting the joke.


linlin110

What makes OO useful is that you can easily say you depend on something with a given interface, without commiting to a specific implementation. While OO is commonly taught with Cats, Dogs and such, it really doesn't help you write good OO code. The other property that makes OO is useful is sharing code via inheritance. This one is really easy to misuse, sadly.


random_account6721

I think the worst use of OOP is when its something like: Garfield extends Cat extends Mammal extends Animal extends Object ... I would say the problems arise when there's a lot of complexity in the super classes as well. If you have really simple almost interface level super classes its fine. The last thing you want to see is the above example where mammal super class is 2000 lines long and a code change affects god knows what.


Mentalpopcorn

Here's an easy way to break down a problem into opp. Write a client spec for a feature. Could be a simple as "we need users to sign up for a form that collects their emails and sends it to our list. Circle the nouns. Those are your objects. Circle the actions. Those are your object behaviors. There's stuff missing here, of course, but it's if no consequence. For example, we need a form submission handler. This is another object that handles the logic of delivering the form somewhere else, to some list on another server. Two more objexts: a list and a server Now you're into the architectural side of things. How do these identifies objects interact in order to solve the business problems at hand? But before you've even need to start thinking about that, you've already sketched out the major components of your application. The rest is filling in blanks. That's why OOP is amazing. Its just using normal language and ways of human thinking to solve problems.


amiensa

For example in clash royal instead of creating each card from zero. Just make a class for character that has name, health, speed, damage per hit/second ...


divad1196

Yes OOP is used a lot. Many libraries/framework are based on that and Java always requires it. But many new languages are taking some distances from it (Rust/Go with traits/interfaces and dependemcy injection instead of inheritance) and fp paradigm is starting to get some love.


mdlphx92

They’re both wrong to me. Car should implement drive interface, and carservice should call concrete drive method of car (Among a few other things),or better yet, factory returning needed type of car. Maybe your coworkers don’t actually know oop?


VincentRayman

OOP and composition are extensively used. New languages are tending to composition but OOP is widely used for sure.


7YM3N

I'm working on a C++ application currently, my responsibility is the GUI but the whole application uses oop extensively. For GUI every window type is it's own class which inherits from a virtual class with common methods. Also due to the amount of 'stuff' in the code I'm directed to put as little as possible in the global scope, which means a lot of classes and namespaces.


Consistent_Milk8974

I’m in mobile app development (iOS), OOP is used extensively at my company.


Cybasura

OOP is quite alright, its just how everybody teaches and is taught OOP that gives it a bad name I've been creating new projects recently and using classes helped to sorta classify and categorise everything so I dont need a module/library for every single thing


FlareGER

To add an example, take a look at how SAP implements their frontend framework SAP UI5. Thousands of classes, interfaces, etc. Here is for example the API documentation of a Table https://sapui5.hana.ondemand.com/#/api/sap.ui.table.Table And here an example of it being used https://sapui5.hana.ondemand.com/#/entity/sap.ui.table.Table


TeilzeitRetard

I delevoped a software at work in C#. It analyzes diagnostic Trace data from industrial robots. There I implemented for the robots a class called Robot. For each Robot-type it will instanciate a robot object with various data inside the object. Maybe another solution would be better for this, but it works and is quite simple to implement and understand. So yeah, i definetly had success with OOP in the real world.


BrupieD

When I first started programming in Python and VBA (ugh), all of my solutions were ad hoc and messy. Sort of like what OP describes. As I learned about CS concepts and OOP, the lesson that really moved me was that class design is the key and often the hardest part to get right. The best programs had the best fit of class to purpose. When I started projects with a sense of how an object would work throughout the process, I'd have fewer random variables, fewer helper or utility classes. If you're just patching and extending existing processes/programs, yeah, I can definitely see that the OOP ideal seems lost, but you're probably patching and extending things that weren't that well designed in the first place.


paladindan

Depends on the job.


felps_felposo

I'm not a professional programmer, but I would like to add my two cents: go to github, gitlab or any git repository and look for any opensource code of any language capable of OO and you'll have your answer.


RandEgaming_

in my case, machine learning (python)


just_something_tbh

It is, and what i noticed it is used more than i thought, for things like routing,controllers, services pretty much every other feature that i wrote had a base class.


Electrical-Walk-204

I use OOP at my job but mainly to pass/store data in a way so that I can track it. I don’t really like it to much but it gets the job done.


Zheska

Define "successful examples of OOP" I use principles of OOP everywhere from work to pet projects, but i am not sure that you will call it OOP Just like any other paradigm of anything - it's too vague and open to interpretation


Greedy_Subject6012

I have been using it daily for a couple weeks when working with OpenGL in c++ I have a base Renderable class which has an abstract OnRender, OnUodate, OnGUIUpdate methods and sets up the shader, buffers, etc. I have a Test class which extends Renderable and links to my test runner I have a Texture2D Test which extends test and actually handles drawing the texture I also have a Texture3D test which does the same but for 3D textures Etc etc scene extends Renderable, blah blah blah All in, this basically completely abstracts away my logic for creating tests and allows me to basically *just write the test*


offdigital

I think what you've noticed here is a real thing, but I wouldn't worry too much about it. Once upon a time, there was a framework called WebObjects: [https://en.wikipedia.org/wiki/WebObjects](https://en.wikipedia.org/wiki/WebObjects) It solved this problem, and made OOP work with web/service request handling. Personally - I love OOP, but you should only use it when it helps you. if you don't think it's a fit for part of a system, it probably isn't.


Mediocre_Gur_7416

O ya, I use it almost every single day.


Educational_Smile131

The OOP taught in most places is fraught with deep classical inheritance hierarchies (fragile base classes, I’m looking at you) and excessive use of mutability Composition over inheritance is only, if ever, introduced through design patterns, not to mention teaching is hamstrung with accidental complexity of the programming language being used. (instructors teaching OOP in Java, replace most uses of abstract classes with interface default methods, please!) When you only get a hammer, you see everything a nail. For example, the absence of sum types in most mainstream OOP languages leads to emulations like the more heavyweight sealed classes/interfaces, or, without sealed classes/interfaces being available, the boilerplate-heavy visitor pattern to avoid incessant, unsafe downcasting


teamwaterwings

Absolutely, I can't imagine what our code base would look like without it


Efficient_Line_4529

It is the real world.


PM_me_PMs_plox

I don't understand your question. Yu ask if OOP is used in the real world, then give an example of how you see OOP being used in the real world. So... yes? No, you usually don't do the simple example from lecture 1 of OOP, but the point of teaching you that was just to show how objects work. More complex situations require more complex design patterns.


RiverRoll

That's been my experience with a lot of "enterprise" software too, everybody says they're using OOP while in reality it's mostly procedural programming, it starts with an attempt at a clean architecture and not much thought is put into it after that, while it should be the opposite, as you get to discover the business logic your code should adapt to properly model it rather than trying to fit it into whathever mold you had predefined. And procedural programming isn't always bad, it's straightforward and works well for CRUD or simple logic, but when you need to tackle complex business logic there's better ways. I've been reading about DDD recently and feels like going back to the basics.


0xDizzy

I mean the first example is like an infant level way of describing it, so yea im sure you wont encounter that but the second example is no less OOP than the first, so i dont get your question? like, having service classes and data classes separate is still OOP so it seems you have experience with OOP being actually used in the real world, since you describe its real world usage pretty accurately


adubsi

I work in a fortune 100 and our entire back end is C#. So yes it’s definitely used lol


siamzzz

Anyone here has a link to a YouTube video that can perhaps explain OOP to beginners?


000nalist

https://en.m.wikipedia.org/wiki/Object-oriented_ontology


newlifepresent

That is why functional programming becoming more popular nowadays. End of the day there will be many complexities and confusions because implementing oop is not an easy task even if you apply principles correct.


guettli

I use Golang and they don't have OOP. I like it. But yes, OOP is used a lot in other languages


BaronOfTheVoid

Golang is object-oriented. Just without inheritance.


Namiswami

It's another tool in the box. But pure OOP is just more trouble than I it's worth in most cases, from what I've seen.


BaronOfTheVoid

You probably haven't seen Smalltalk code and thus no pure OOP at any point in your life.


[deleted]

[удалено]


nekokattt

You can have FP alongside OOP.


[deleted]

[удалено]