3 ms·
obviously when they refer to loose coupling, they're refer to that between interface and hidden states/implementation of object. It's very easy to deliberately
by nsonha 2y ago
obviously when they refer to loose coupling, they're refer to that between interface and hidden states/implementation of object.
It's very easy to deliberately miss the point and complain about the "tight coupling" that, by design, prevents messages to be sent to/called upon invalid states, which functional programming also has, albeit with different a approach using static type inference & pattern matching.
- the_af 2y agoThe tight coupling the OP refers to is between different components, in this case different classes in the same inheritance tree. If you use implementation inheritance, i.e. a base class with a tree inheritance of derived classes, there's coupling between the derived classes and the base class, because changes done carelessly in the base class (for example, to accommodate one additional child class) may impact the behavior of already existing derived classes. There are all sorts of principles to minimize this risk, but they are there precisely because it's such a big risk. Therefore "inheritance as reuse" introduces dangerous coupling, but it's not a case of the "interface being coupled to the implementation of the object".
- nsonha 2y agono one ever brought up "inheritance as reuse" in this thread, don't straw man. It's called OOP, NONE of those letters stands for "inheritance"
- the_af 2y ago> no one ever brought up "inheritance as reuse" in this thread, don't straw man. Yes they did. I quote one of the statements at the top of this thread: > But in real life, when there is a team, you run into the fragile base class [1] constantly and changing that base class causes horrible issues across your code base. The "fragile base class" is one of the problems of "inheritance as reuse". It simply doesn't occur with interface inheritance (the other common type of OOP inheritance). > It's called OOP, NONE of those letters stands for "inheritance" That line of conversation is fruitless. We're discussing OOP as practiced, not as defined by Alan Kay (who came to regret the name "OOP" anyway). OOP as practiced is all about inheritance, and sadly, its pitfalls. This is exactly what other people in this thread are discussing pros and cons of! Not OOP in academia, but in practice. Also, it's mentioned in the article which you hopefully have read: In this post I use the word “OOP” to mean programming in statically-typed language with: - Classes, that combine state and methods that can modify the state. - Inheritance, which allows classes to reuse state and methods of other classes. - Subtyping, where if a type B implements the public interface of type A, values of type B can be passed as A. - Virtual calls, where receiver class of a method call is not determined by the static type of the receiver but it’s runtime type.
- nsonha 2y ago> Tight coupling is the basis of oop. A method is tied to an instance. Methods cannot be composed with other methods or functions without instantiating state. Methods cannot be moved into other scope. > The literal definition of an object is a tightly bound set of methods that cannot ever be used without instantiating state. That is the nonsensical point I responded too, you're bringing up an actual bigger debate that's out of scope.
- ninetyninenine 2y ago>obviously when they refer to loose coupling, they're refer to that between interface and hidden states/implementation of object. Right and I'm saying it's the tight coupling of Objects themselves that's the main problem. >It's very easy to deliberately miss the point and complain about the "tight coupling" that, by design, prevents messages to be sent to/called upon invalid states, More like you missed my point. You should avoid coupling logic and state as much as possible period. OOP encourages this. You have one state called A, and A has 20 methods attached to it. Boom now All methods and A are tightly coupled. At most one should have only a simple setter and getter on A, and all the transformational logic be pure functions and decoupled from the changing of state. Oh and you can use type checking to prevent logic to operate on invalid state.
- nsonha 2y ago> avoid coupling logic and state as much as possible period depending on how you define "state". In OOP, the coupling is between a bunch of transitions (as a single class) to a bunch of states (as a single type). It's actually *loose* coupling that is the problem here because that set-up can easily produce invalid states. It can be addressed with the builder pattern. Tight coupling is a problem alright, no one is denying that. It's just there is nothing wrong conceptually about "coupling state to the logic", that is a non-problem, and "tight coupling" has never meant that.
- ninetyninenine 2y agoHighly disagree state to logic is a huge problem. Once you couple state and logic together you lose modularity so such couplings need to be avoided. The reason is as I said. Once state and logic are coupled it becomes entangled with all the logic related to the same state. What you’re referring to is a transaction. Where multiple states must be changed at the same time as a transaction. And while you don’t explicitly say it you’re implying that transactions are required. They can’t be avoided. And that’s where I agree. Coupling state and logic is a problem and must be avoided as much as possible, but you can’t fully avoid it. The main problem with oop is that it promotes the coupling of state and logic everywhere. The style of programming maximizes tight coupling all over the place. That is the problem and the insight you’re not seeing. Years of doing oop makes you feel that such couplings can’t be minimized. This makes oop highly unmodular. It makes it so that refactoring a of code are normal almost every time a new feature is introduced. If you want more insight into what I’m talking about you can follow some of the branching threads that I’m in where I write examples and maybe you’ll see what I’m talking about.