I am reviewing a proposed OO software architecture that looks like this:

Base

Foo

Something

Bar

SomethingElse

Where Base is a static class.

My immediate thought was that every object in any class will inherit all the methods in Base which would create a large object. Could this cause problems for a large system? The whole architecture is hierarchical.. the 'tree' is much bigger than this really. Does this sort of architecture have a name (hierarchical?!). What are the known pros and cons?

@ArnisL. Not necessarily. Issues with inheritance and maintainability aside - if the objects can be represented naturally in hierarchical way, then it's the most natural way of doing so - which often leads to the most obvious, simplest and practical way of representation. Of course, in many cases you just can't force things into hierarchies, and as such it's often a bad idea.
–
zxcdwSep 11 '12 at 12:12

3

You should really ask what they are trying to achieve by having the base class (utility methods, common data fields, leaving things open for some kind of dependency injection?). The relevant anti-pattern name is BaseBean, and I'm struggling to think of any scenario where you could keep the base light enough that it applies to all objects, yet still somehow relevant. As others have pointed out, however, performance is not necessarily going to be bad - it would depend on what's in that base class.
–
Daniel BSep 11 '12 at 12:56

7 Answers
7

The real question is: WHY does the architect want everything to inherit from base? What's the utility of doing so?

If it's for something like serialization interfaces, then it MIGHT make sense if you will need a general serialization facility. But make sure that you actually will need EVERY class in the system to have that functionality. If you don't, then you end up needlessly inflating each class, AND you'll end up having to implement (or stub out) functionality in classes where that functionality doesn't make sense.

I would NEVER implement my own 'uber-base' like this in a system, because I can't conceive of any functionality or interface that I would want in EVERY object EVERYWHERE in my system. The only thing I can think of that it might be useful for is something like heterogeneous containers, but I've never been in a situation where I wanted a completely heterogeneous container - I generally want a set of classes, not just any random thing under the sun to go into my containers.

Unless the architect can demonstrate why they want this uber-base, I'd leave it out.

What do you mean when you say "large object"? Memory footprint? That shouldn't really be a problem.

If the methods are static (is that what you mean by "static class"?), they're part of the class, not of each instance. But even if they're instance methods, they shouldn't affect the memory footprint of an object.

If you mean "large object" as in "containing a lot of methods that you rarely use", then... yes, that might be an issue. The shared base class should probably only contain methods that really are shared.

The question is what exactly do you aim to achieve with this architecture? the .NET Framework has a shared Object class, as superM mentioned, but after that, the hiererachy is flat, with most classes inheriting directly (though implicitly) from Object.

Having each class inherit from a single base class might create a large object depending on what you put in the base class. But, the advantage of this is that all the utility type of functions can be put in the base class and this will offer uniform implementation.

I'm not sure if such architecture has a name, but this is exactly what Microsoft has done (except that not all the methods in the base class are static). In C#, for instance, every type is inherited from the Object class. So every type has methods like Equals(...), GetHashCode() etc. In many MVC applications there is base controller, which is inherited by all controllers.

This approach has a lot of advantages. Here are some of them:

common interface for all objects

a set of mandatory features, which now every object will have

flexibility: new common features can be easily added

etc.

The disadvantage is that there might be objects which will never need these methods, but will still inherit them. Though this disadvantages can be easily ignored.

I don't know for sure, but the fact is you still have the common Object methods for them too.
–
superMSep 11 '12 at 11:36

superM: that's because of the automatic boxing/unboxing. The compiler/runtime make "int i = 5; i.ToString();" transparent for you, but behind the scenes it's boxing a primitive '5' into a System.Int32.
–
Avner Shahar-KashtanSep 11 '12 at 11:37

@superM: there is a very good reason why value types are in fact no object - because the memory footprint of small types like int, char and byte would multiply. According to this stackoverflow.com/questions/631825/net-object-size the minimum object size is 12 bytes. Imagine if each 'C# byte' value would need at least 12 bytes in memory.
–
Doc BrownSep 11 '12 at 11:45

1

@DocBrown: Values types do inherit from object. All structs inherit ValueType which inherits Object, and System.Int32 for example is a struct. See msdn.microsoft.com/en-us/library/saxz13w4.aspx. The answer in your link specifically refers to reference types.
–
ChrisSep 11 '12 at 14:25

My immediate thought was that every object in any class will inherit all the methods in Base which would create a large object.

This is incorrect. The reference to the parent type is an extra pointer at worst. If the base type has only methods or static members, it won't add much of anything to the subtype when instantiated.

Could this cause problems for a large system? The whole architecture is hierarchical.. the 'tree' is much bigger than this really.

Deep inheritance hierarchies are a code smell, sure. Having a common base class is often times troublesome because there are very, very few things that apply to everything and behave the same. It often leads to leaky abstractions and violation of the Liskov Substitution Principle.

Where Base is a static class.

This seems a little odd. If the base class is essentially empty from an instance member perspective, that runs into a variety of other issues. At that point specifying a variable of that type allows you to do almost nothing with it, which is... counterproductive.

A static base class will allow using of all public or protected functions and members of that base class everywhere through your object hierarchy, without referring to a specific class name (or namespace). This means you will just get global functions and members all throughout your system, which "disables" some of the main ideas of object orientation. You will get a much better architecture when you put those static methods into separate utility classes and group them thematically. Otherwise, such a base class could too easily become a "god class", which is a well-known anti-pattern.

IMHO the whole thing would make sense to a certain degree only if you

don't add any functions or members to the static base class

need a mixed-type generic container for your objects and you don't have any built-in language support for that