Tag Info

Hot answers tagged

67

Last time I tried to start a refactoring with unforeseen consequences, and I could not stabilize the build and / or the tests after one day, I gave up and reverted the codebase to the point before the refactoring. Then, I started to analyze what went wrong and developed a better plan how to do the refactoring in smaller steps. So my advice for avoiding ...


51

Is it just a symptom of my previous classes depending too tightly on each other? Sure. One change causing a myriad of other changes is pretty much the definition of coupling. How do I avoid cascading refactors? In the worst sort of codebases, a single change will continue to cascade, eventually causing you to change (almost) everything. Part of ...


41

So, what am I missing? Dependency Injection decreases coupling between a class and its dependency. But it increases the coupling between a class and its consumer (since the consumer needs more info to create it) and the dependency and its consumer (since the consumer needs to know the dependency to use). Very often, this is a good trade off. The class ...


33

The approach your professor proposes is best described as stringly typed and is wrong on almost every level. Coupling is best reduced by dependency inversion, which does so by a polymorphic dispatch, rather than hardwiring a number of cases.


30

In theory, loose function-data coupling makes it easier to add more functions to work on the same data. The down side is it makes it more difficult to change the data structure itself, which is why in practice, well-designed functional code and well-designed OOP code have very similar levels of coupling. Take a directed acyclic graph (DAG) as an example ...


22

In layman's words: Not all users use all of a company's apps Different users have different needs Why force an user to buy a full package when he/she needs only a part ? (Ok, Google apps are free, but other software maker's aren't.) Having those apps separate makes it possible to be updated separately and, most importantly, sold separately. The fact that ...


21

Suppose you have a subsystem S that depends on a database connection D. Without dependency injection, there is a relatively tight coupling between S and D, because S needs to know both how to use D and how to create it. The rest of the system, however, can be blissfully unaware of this dependency between S and D. With dependency injection, the coupling ...


18

Your professor is doing it wrong. He's trying to completely decouple the view and model by forcing communication to travel via string in both directions (view doesn't depend on model and model doesn't depend on view), which totally defeats the purpose of object-oriented design and MVC. It sounds like instead of writing classes and designing an OO-based ...


17

It sound like your refactoring was too ambitious. A refactoring should be applied in small steps, each of which can be completed in (say) 30 minutes - or, in a worst-case scenario, at most a day - and leaves the project buildable and all tests still passing. If you keep each individual change minimal, it really shouldn't be possible for a refactoring to ...


15

Well, your first three points are actually about other principles than coupling. You always have to strike a balance between oft-conflicting design principles. Your fourth point is about coupling, and I strongly agree with you. Coupling is about the flow of data between modules. The type of the container that data flows in is largely immaterial. Passing ...


12

There is a balance that needs to be achieved between looseness of coupling and complexity. As the person responsible for the overall architecture, you need to strike that balance. When we call a ToString() method on an object, we can do so safely because we know all of our classes derive from a base class that has a ToString() method, and that method can ...


12

I've been involved in projects like this twice now (both using nuget with .NET), and I would say that on balance it is a good idea. But your mileage may vary. Don't think for a minute that it's a panacea, that it's going to solve all of your problems without causing new ones. Release management will gain a whole new layer of complexity, you'll need to deal ...


11

enums (or public static final Strings) should be used instead of magic Strings. Your professor doesn't understand OO. For example having a concrete Vehicle class? And to have this class understand the make of a bicycle? Vehicle should be abstract and there should be an concrete subclass called Bike. I would play by his rules to get a good grade and then ...


11

In case you didn't know it already take this insight: The concepts of object-oriented and closures are two sides of the same coin. That said, what is a closure? It takes variable(s) or data from surrounding scope and binds to it inside the function, or from an OO-perspective you effectively do the same thing when you, for example, pass something into a ...


11

How can I avoid this kind of cascading refactor in the future? Wishful Thinking Design The goal is excellent OO design and implementation for the new feature. Avoiding refactoring is also a goal. Start from scratch and make a design for the new feature that is what you wish you had. Take the time to do it well. Note however that the key here is "add ...


10

TO make your code loosely coupled here are a few simple things to remember: Part 1: Technically known as "Separation of Concern". Each class has a specific role, it should be handling business logic or application logic. Try and steer clear of class that combine both responsibilities. i.e. A class that manages (broad term) data is application logic while a ...


10

My recommendation is: Use addTrack( ITrack t ) but be sure that ITrack is an interface and not a concrete class. Album doesn't know the internals of ITrack implementors. It's only coupled to the contract defined by the ITrack. I think this is the solution that generates the least amount of coupling.


9

If you really need coordination between those two classes, write a CsvCoordinator class that encapsulates your two classes, and test that. However, I dispute the notion that CsvRecord is not independently testable. CsvRecord is basically a DTO class, is it not? It's just a collection of fields, with maybe a couple of helper methods. And CsvRecord can be ...


8

Constants that are specific to a class should go in that class's interface. Constants that are really configuration options should be part of a configuration class. If you provide accessors for the configuration options in that class (and use them in place of the constants elsewhere), you won't have to recompile the whole world when you change a few ...


8

Good question, simply put, decouple. That's the way to go here, you do not want to be tied to the version of java. There's one scenario you don't decouple: if your technology will allow for non-type-specific objects to be sent over the wire, that is, if you can use the current java objects now as a YAGNI, and the replacement with a different type that you ...


8

From (the wonderful) book Working Effectively with Legacy Code by Michael Feathers: When you break dependencies in legacy code, you often have to suspend your sense of aesthetics a bit. Some dependencies break cleanly; others end up looking less than ideal from a design point of view. They are like the incision points in surgery: there might be a scar ...


7

From the comments I see you're using Java. Have a look at various Queue implementations. Particularly, BlockingQueue is useful for producer-consumer scenarios. You could have two queues: one between Source (producer of data) and Process (consumer of data), and another between Process (producer of results) and Persist (consumer of results). With ...


7

I would say it's definitely not as bad as a God Object or Super Object. Those are a whole different animal that is hard to write, maintain, debug, and test and they should be avoided at all costs. As far as the namespace goes, that's definitely a legitimate concern, and if you are finally getting to the point where your namespace is becoming overcrowded I ...


7

Afferent coupling can most easily be assessed in terms of how much pain it causes/saves because of change necessity or likelihood. For instance, take your wheel class and let's say that a lot of other modules use it to build various kinds of vehicles. If the wheel class is extremely stable, then this afferent coupling is beneficial since vehicles need ...


7

I strongly disagree that it increases coupling. Without dependency injection you have tight coupling between a sub system and the concrete implementation of the dependency. With dependency injection you have decoupled the sub system from the implementation of the dependency. Making the argument that it increases coupling between the consumer and this sub ...


6

Using 'industry experience' is a poor argument. Your professor needs to come up with a better argument than that :-). As others have stated, the use of magic Strings is certainly frowned upon, using enums is considered far safer. An enum has meaning and scope, magic strings do not. Aside from that, the manner in which your professor is decoupling concerns ...


6

I think you have a good point, the magic strings are bad. Someone on my team had to debug a problem caused by magic strings a couple weeks ago (but it was in their own code that they wrote so I kept my mouth shut). And it happened... in industry!! The advantage to his approach is that it might be faster to code, especially for small demo projects. ...


6

As far as I can tell, your example closely matches the strong coupling, as it is defined in Wikipedia: Strong coupling occurs when a dependent class contains a pointer directly to a concrete class which provides the required behavior. The dependency cannot be substituted, or its "signature" changed, without requiring a change to the dependent class. ...


6

I know you're trying to simplify your scenario to make it easier to discuss, but why does the OrderItem care about the Header? The Header is Aggregator (called the "Root" in DDD) and it is responsible for knowing about its components (OrderItem being one of them). If you're discussing special cases like Discounts being applied to Orders containing for ...


6

The main arguments for #1 are ease of implementation and upgrades, but does it satisfy your requirements? In your arguments for #2, you indicate that the Java API and REST API may likely change independently. This means they are separate concerns and you are not repeating yourself by using separate classes. Just because two things look the same, doesn't ...



Only top voted, non community-wiki answers of a minimum length are eligible