8

I know most people hate flat and long functions, and hate when code is not full of ISomethings.

The problem is that I guess my mind works in different way, and I always have problems with that type of code in any non-trivial solution.

So, since most of people enjoy explosive number of functions, can you describe what is the preferred method when dealing with unknown code-bases written in this way?

So far, for me, it looks like:

I have a object with interface IFoo, great, I need to extend it with method Bar1. Reverse lookup, we land nowhere, global search on who implements IFoo, it's Baz1, Baz2, Baz3, Baz4, an they are created by 3 class factories. So we start one by one, definition of Baz1, looks nice, but it's behaviour is completely dependent on parameters used when object was created through class factory. And what's worse, it's just a wrapper around some other functionality of yet another class with IFooBar. Which again uses some internal implementation of classes with ISomethingElse, which again turns into an explosive graph.

How do you navigate all that effectively?

4
  • First, I go read this: faqs.org/docs/artu/ch01s06.html then you read this: faqs.org/docs/artu/unix_and_oo.html Aug 31, 2011 at 16:08
  • Especially the 6th paragraph in the second link. Aug 31, 2011 at 16:10
  • 3
    This is often a problem with overly abstracted object oriented code. Abstraction and polymorphic classes are of course important tools but sometimes they are overused. These are good things, but sometimes they are overused and you can write bad code in any methodology.
    – JohnB
    Jul 23, 2013 at 8:04
  • Above links are broken.
    – ximiki
    Feb 11, 2020 at 20:58

3 Answers 3

3

Sounds like some inappropriate coupling is going on.

There are some tools out there that make this a little easier. In C# I use CodeRush, which includes a handy navigation utility to "jump to implementors" for an interface definition, and similar.

3

You don't. This is the point in writing code that way.

You don't need to know about any of those implementations. You just have to know about what you're adding.

Now you say that you need to add a method to IFoo. Why do you? Is it some functionality you need to call in every class which implements IFoo?

IFoo foo = FooFactory.Create(info);
foo.Action1();

if (foo.Check == "Yay")
{
    foo.Action2();
}

foo.Action4(); // Maybe I'm adding this line

while (foo.StillActive)
{
    foo.Action3();
}

If so then you need to know what it's going to do for each of those cases -- so you probably need to understand the factory class, to know what those cases are.

But if not then you probably shouldn't add your method to IFoo. If it's only going to be used in one of those classes, create another interface and do this:

IBlah fooBlah = foo as IBlah;
if (fooBlah != null) fooBlah.DoSomething();
2
  • 1
    Say you have a car. It has methods Drive, Start, Stop. Now you also need a method Park. BOOOM, stuff hits the fan, because suddenly you have to either change Lorry, ElectricCar, GoCart, Tractor, etc., etc., with the methods, or, you have to implement IParkableCar which is completely nuts, because suddenly GoCart is not a parkable car.
    – Coder
    Aug 31, 2011 at 16:25
  • 2
    This is why OO is not well described by real-life objects. If your application is only going to call Park on ElectricCar then it's fine to implement IParkableCar on the ElectricCar class and not on the other Vehicles. But if your application needs to Park all types of vehicle then it should become a part of IVehicle and thus you MUST consider implementation on every class of Vehicle.
    – pdr
    Aug 31, 2011 at 16:35
0

It depends on your IDE. With Visual Studio and ReSharper, finding the implementations and usages of an interface is extremely easy. I guess I'm the opposite of you though, I find smaller functions to be easier to comprehend than large ones.

Not the answer you're looking for? Browse other questions tagged or ask your own question.