Timeline for How far can you push Object Oriented Programming?
Current License: CC BY-SA 4.0
20 events
| when toggle format | what | by | license | comment | |
|---|---|---|---|---|---|
| May 15, 2024 at 12:07 | vote | accept | candied_orange | ||
| May 14, 2024 at 21:42 | comment | added | Ben Cottrell | @RobertBräutigam But in the situation I'm referring to here there is no internal state because the data is owned by external entities, so the responsibility and authority over that data belongs to some other third party; yet applications still need to be able to build logic around this externally-owned data | |
| May 14, 2024 at 8:48 | comment | added | Robert Bräutigam | @BenCottrell Immutability, while good, is not enough. I want responsibility / authority over my internal state. It is the only way to really have maintainability. Data does not just float around benevolently in an application, it influences behavior, has its own logic and meaning. The moment I expose something, even if immutable, that semantics / logic / meaning becomes shared. I.e. I lose authority and responsibility. I can not make sure that data is used properly anymore. So if anything about this meaning / logic needs to be changed, I'll have a mess on my hands. | |
| May 14, 2024 at 8:22 | comment | added | Ben Cottrell | @RobertBräutigam I agree there, but the origin of my first comment is in relation to whether it's OK to have Clean/Layered architecture inside of an application, reliant upon DTOs (which I think could safely be made immutable in most cases), as opposed to encapsulating data and behaviour inside a class - the complexities I'm describing are one of the main reasons for using DTOs instead of putting data inside classes which are doing most of the work; avoiding 'real' business logic being polluted by infrastructure-layer concerns of retries, error handling, serialisation, configuration, etc. | |
| May 14, 2024 at 8:00 | comment | added | Robert Bräutigam | @BenCottrell There's no real difference between objects on different levels. The high-level objects would 'look' the same as the low-level ones. They all are business-relevant on their own level, and use at most a handful of collaborators to do their job. That is why it doesn't matter how much technical stuff happens behind an object or method call. | |
| May 14, 2024 at 7:48 | comment | added | Ben Cottrell | Your statement "when the proper abstractions exist" really ignores the entire problem that I'm describing, which is that those abstractions are where nearly all of the time and effort needs to be focused, and where nearly all of the code will exist too. The high-level implementation that you're talking about is a mere triviality barely worth mentioning as all it will be doing is essentially connecting a few objects together, whose paths may be trivially covered by tests. | |
| May 14, 2024 at 7:45 | comment | added | Ben Cottrell | @RobertBräutigam of course the technical stuff matters; it's a major source of complexity and therefore maintenance issues. There's a big difference between working with "local" objects which source their data entirely from in-process memory compared with those which depend upon external sources/processes - infrastructure and external systems outside of your control can change and fail in ways which are typically hard to anticipate, and indeed the data they store may be subject to other external forces too. This is different to local objects which don't have any of these concerns. | |
| May 13, 2024 at 12:37 | comment | added | candied_orange | @Ewan what I'd like is to push OOP as far as I reasonably can and stop before I make a mess. | |
| May 13, 2024 at 8:59 | comment | added | Robert Bräutigam | @BenCottrell You seem to be concentrating on technical matters a lot. It doesn't matter at all how much technical stuff happens when calling a method, as long as the method properly delegates stuff to other objects, for example for making the request, checking the JWT, etc. The whole story you described could be a single short expression, when the proper abstractions exist. The important part is the requirement and that I can easily find, read, validate and potentially change the high level implementation of it if need be. | |
| May 13, 2024 at 7:54 | comment | added | Ewan | @candied_orange do you care about the internal implementation of the hashtree object or just that your code doesn't see any getters? If its the latter then you can make an OOP version easy, if it's the former then I'd like more detail on why you think an implementation is impossible | |
| May 13, 2024 at 7:25 | comment | added | Ben Cottrell | I find it problematic to encapsulate data + behaviour into a single class whenever dealing with inter-dependent data from multiple external sources; For example, consider a business rule which uses data from an inbound HTTP request to fetch a JWT Bearer token cached in redis, which in-turn leads us to query a database (based on the JWT claims and the inbound request together), which in turn requires sending a request to a downstream API, and so-on. Trying to encapsulate this chain of events and all of its data into a single class is in danger of becoming a "God object". | |
| May 12, 2024 at 17:03 | comment | added | candied_orange | @Ewan inheriting won’t change the interface. Wrapping doesn’t move it to be with the data. It does let you isolate the non object oriented code. So maybe we’re saying the same thing different ways. I just wanted to be sure. | |
| May 12, 2024 at 15:23 | comment | added | Ewan | @candied_orange This is where you premise is week imo, you can always move the method, even if its a 3rd party lib you can inherit or wrap it. The question is 1. does that make the code better and 2. are those methods what people mean when they say "dont have getters" | |
| May 12, 2024 at 15:20 | comment | added | Ewan | @Ced I think you are still going to have other UI classes where you go onclick => account.display etc and you will definitely be editing NumberView to get it to look right | |
| May 12, 2024 at 14:30 | comment | added | candied_orange | As for layered and clean architecture, output ports are a nice alternative to always using return. You're facing an object through its interface rather than sneaking back inside. Which one you're talking to is configured elsewhere so you aren't coupled to that. They just take a little extra work to test in isolation since you end up needing a mock. Not a framework mind you. Just a little hand rolled mock will do. | |
| May 12, 2024 at 14:20 | comment | added | candied_orange | I agree with this answer. I have struggled with this exact issue since learning OOP. I struggle with it when teaching OOP. The fuzzy "how frequent to shower" issue is the crux. I've only found one concrete way to deal with it. Ask if you can move the method to the data. If you can't that's where OOP dies. Your code beyond here isn't under it's protection anymore so look out. People can program without OOP. It's not the end of the world. But it's promises end there. It can be delt with. Just please, don't resort to CORBA. | |
| May 12, 2024 at 13:01 | comment | added | Ced | @Ewan but most importantly is that your account object is closed. You know how its data is going to be used. Which you cannot know in advance with Account.GetTotalAsPrimitiveType(). The result could be used for display, a calculation, anything really, the point is you do not know. Whether that's a real issue is another question | |
| May 12, 2024 at 13:00 | comment | added | Ced | @Ewan one difference is that you are now working with 1 class instead of two (the view can be hidden), with the domain object acting kind of as a facade for the view with Account.displayCard, Account.displayDetail. This also adds more discoverability than the more common: AccountCard(account), AccountDetailView(account). And yet another benefice is that your object is now a tree with the domain at the top. So your object tree goes from business relevancy to details. | |
| May 12, 2024 at 11:02 | comment | added | Ewan | I agree about the DTOs but is Account.display really better than Account.GetTotalAsPrimitiveType() ? It seems to me that NumberView is leaking to Account as much as Account would leak to the UI | |
| May 12, 2024 at 9:08 | history | answered | Robert Bräutigam | CC BY-SA 4.0 |