Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
Our company keeps a MiscUtilities class that consists solely of public static methods that do often unrelated tasks like converting dates from String to Calendar and writing ArrayLists to files. We refer to it in other classes and find it pretty convenient. However, I've seen that sort of Utilities class derided on TheDailyWTF. I'm just wondering if there's any actual downside to this sort of class, and what the alternatives are.
Rather than giving personal opinion, I will quote from an authoritative source in the Java community, and examples from 2 very reputable third party libraries.
A quote from Effective Java 2nd Edition, Item 4: Enforce noninstantiability with a private constructor:
Occasionally you'll want to write a class that is just a grouping of static methods and static fields. Such classes have acquired a bad reputation because some people abuse them to avoid thinking in terms of objects, but they do have valid uses. They can be used to group related methods on primitive values or arrays, in the manner of java.lang.Math or java.util.Arrays. They can also be used to group static methods, including factory methods, for objects that implements a particular interface, in the manner of java.util.Collections. Lastly, they can be used to group methods on a final class, instead of extending the class.
Java libraries has many examples of such utility classes.
Apache Commons Lang follows the TypeUtils naming convention
ArrayUtils, StringUtils, ObjectUtils, BooleanUtils, etc
Guava follows the Types naming convention
Objects, Strings, Throwables, Collections2, Iterators, Iterables, Lists, Maps, etc.
The package summary actually has a specific section on classes of static utility methods
Another entire package consists of nothing but utility classes for working with Java primitives, Ints, Floats, Booleans, etc.
Short summary
Prefer good OOP design, always
static utility classes have valid uses to group related methods on:
Primitives (since they're not objects)
Interfaces (since they can't have anything concrete of their own)
final classes (since they're not extensible)
Prefer good organization, always
Group utility methods for SomeType to SomeTypeUtils or SomeTypes
Avoid a single big utility class that contains various unrelated tasks on different types/concepts
Convenient, most likely.
Possible to grow into a scary, hard to maintain swiss-army-rocket-chainsaw-and-floor-polisher, also most likely.
I'd recommend separating the various tasks into separate classes, with some logical grouping besides "won't fit anywhere else".
The risk here is that the class becomes a tangled mess nobody fully comprehends and noone dares to touch - or replace. If you feel that is an acceptable risk and/or avoidable under your circumstances, nothing really prevents you from using it.
I've never been a fan of the MiscUtilities class. My biggest issue is that I never know what is in it. Anything filed under miscellaneous is not discoverable. Instead I prefer to use a common dll that I can import into my projects that contains well named, separated classes for different purposes. The difference is subtle, but I find that it makes my life a little easier.
For languages that support functions, this sort of class is undeniably bad form.
For languages that don't, this sort of class isn't, and is probably superior to extending other classes with random utility methods. The static utility methods, because they are in some other class, can only use the public interface of the objects they handle, which decreases the likelihood of certain kinds of bug. And this approach also avoids polluting public interfaces with a random grab bag of whatever people happened to find useful at the time.
There's a certain amount of personal style involved of course. I'm not a big believer in classes that provide everything under the sun (even C++'s std::string is a tad over-featured for my taste) and tend to prefer to have helper functionality as separate functions. Makes maintenance of the class easier, forces the public interface to be useful and efficient, and with duck-typing style mechanisms the external functions can be used across a wide range of types without having to duplicate source text or share base classes and so on. (The oft-derided algorithms in the C++ Standard Library are a good demonstration of this, imperfect and verbose as they are.)
That said, I've worked with many who complain about strings that don't know how to interpret themselves as filenames, or split themselves into words, or what have you, and so on. (I pick on strings because they seem to be the prime target for utility functions...) I happen to think there are unseen maintenance and reliability costs associated with having large classes like that, quite apart from the ugliness of having a nominally simple class that's actually a vast illogical mishmash of unrelated concerns whose grubby fingers end up poking themselves into every last corner -- because your self-tokenizing string needs some kind of container to put the tokens in, right?! -- but it's a balancing act, even if my wording suggests it's more clean-cut than that.
I'm not a big believer in the notion of "OO dogma", but perhaps the paranoid might see it at work here. There's no good reason that all functionality should be attached to a particular class, and many good reasons why it should not. But some languages still don't allow the creation of functions, which does nothing to remove the need for them and forces people to work around the restriction by creating classes that consist of nothing but static methods. This rather overloads the meaning of the class concept, to my mind, and not in any good way.
So that IS a good reason to rail against this practice, but it's pretty futile unless the language changes to accommodate what people need to do. And languages don't come without functions unless their designers have an axe to grind, or there are technical reasons for it, so I should think that change in either case is unlikely.
I suppose the executive summary is: no.
Well, bad utility classes are derided on TheDailyWTF :)
There's really nothing wrong with having a generic utilities class for miscellaneous static business functions. I mean, you could try to put it all into a more object oriented approach, but at what cost in time and effort to the business and for what trade-off of maintainability? If the latter outweighs the former, go for it.
One approach you may be able to take, depending on the language, etc., is to perhaps move some of the logic into extensions on existing objects. For example, extending the String class (thinking in C# here) with a method that tries to parse the string into a DateTime. An in-house library of extensions just enhances the language with your business' own little DSL(s).
The company I work for has a class like that in its repository. Personally I find it annoying because you have to be really intimate with the class in order to know what it's useful for. Consequently, I've found myself re-writing methods that this class already covers! Double annoying because I've now wasted my time.
I would prefer a more object oriented approach that would lead to expandability. Have a Utilities class for sure, but inside it put other classes that expand toward specific functionality. Like Utilities.XML, Utilities.DataFunctions, Utilities.WhateverYouWant. That way you can expand and eventually take your 20 function MiscUtilities class and turn it into a 500 function class library.
A Class Library like this could then be used by anyone, and added to by anyone (with privileges) in a logically organized way.
I think the wrong defect of such a class is that it break Separation of concerns principle. I usually create multiple "Helpers" class to contains widely used, public static methods, for example ArrayHelpers to writing ArrayLists to files, and DatesHelper to converting dates from String to Calendar.
Moreover, if the class does contain complicated methods, it's better to try to refactor them using more object-oriented tecnique.
You can always switch from your "Helpers" class to the use of various OO pattern, leaving your old static methods to function as a Facade.
Yuo'll find great benefits everytime you'll be able to do so.
I keep a separate misc class for each project, and copy/paste code from other projects as needed. Perhaps not the best approach, but I prefer to avoid cross-project dependencies.
Examples of things in my helper class:
hex2, hex4, and hex8 (accept integer parameters, except hex8 which has integer and uinteger variations; all versions ignore higher-order bits)
byt (convert 8 lsb's of argument into a byte)
getSI, getUI, getSL, getUL (each takes a byte array and an offset, and returns the little-endian signed word, unsigned word, signed 32-bit word, or unsigned 32-bit word at that offset
putSI, putUI, putSL, putUL (takes a byte array, offset, and a value to put there in little-endian format)
hexArr (converts a byte array or portion thereof into a hex string)
hexToArr (converts a hex string to a byte array)
Zap(of T as iDisposable) (takes a byref iDisposable; if not Nothing, disposes it and sets it to Nothing)
Many of those are only useful when fiddling with binary data, but none of them is really domain-specific. Maybe the first six could go in a BinaryHelpers module, but I'm not sure where Zap should go other than in a misc utilities class.
Utility classes aren't bad, in and of themselves. They can be (mis|ab|over)used at times, but they do have their place. If you have utility methods for types you own, consider moving the static methods to the appropriate types. Or creating extension methods.
Do try to avoid a monolithic utilities class - they may be static methods, but they will have poor cohesion. Break up a large set of unrelated functions into smaller groupings of related functionality, much like you would your "normal" classes. Name them *Helper or *Utils, or whatever your preference is. But be consistent, and group them together, perhaps in a folder within a project.
When utility classes are broken up as described, you can create methods for working with specific types - primitives or classes, such as arrays, strings, dates and times, and so on. Admittedly, these wouldn't belong anywhere else, so a utility class is the place to go.
Personally, I often find such a class handy - even if only in the short term. That said, I try not to share them between projects. I would not keep a global version, but write one specific to each project - otherwise you're incorporating dead-weight which may cause issues for security or architecture.
What I do for my personal projects is keep a misc library but rather than adding a reference in my projects, I paste the relevant bits of code in to the relevant places. It's technically duplicaintg it, but not within a single solution and thats the important thing. However I don't think this would work on a larger scale, too messy.
I generally don't have a problem with them, although, like all things, they can be abused:
They grow wildly large, so that most problems that use the class don't use 99% of the functions.
They grow wildly large, so that 90% of the functions aren't used by any program still in use.
Often they are a dumping ground for functions which are specific to one domain. They should be pared off to a similar class use just by program in that domain. Often, these function would be better off incorporated into proper classes.
I used to have, in every project, a module called MiscStuffAndJunk. It was a place to hold everything that didn't have a clear place to go, either because the functionality was a one-off, or because I didn't want to change my focus, so as to do a proper design for a function that was needed by but extraneous away from what I was currently concentrating on.
Still, it these modules are clearly in violation of OO design principles.
So nowadays, I name the module StuffIHaventRefactoredYet, and all is right with the world.
Depending on what your static utility functions actually do and return, it may be cause problems unit testing. I have come across a method in a class that calls a static function on a static class that return things I do not want in my unit test, rendering the whole method untestable...
Related
I wanted to ask you all for you opinions on code smells in Objective C, specifically Cocoa Touch. I'm working on a fairly complex game, and about to start the Great December Refactoring.
A good number of my classes, the models in particular, are full of methods that deal with internal business logic; I'll be hiding these in a private category, in my war against massive header files. Those private categories contain a large number of declarations, and this makes me feel uneasy... almost like Objective-C's out to make me feel guilty about all of these methods.
The more I refactor (a good thing!), the more I have to maintain all this duplication (not so good). It just feels wrong.
In a language like Ruby, the community puts a LOT of emphasis on very short, clear, beautiful methods. My question is, for Objective C (Cocoa Touch specifically), how long are your methods, how big are your controllers, and how many methods per class do you all find becomes typical in your projects? Are there any particularly nice, beautiful examples of Classes made up of short methods in Objective C, or is that simply not an important part of the language's culture?
DISCLOSURE: I'm currently reading "The Little Schemer", which should explain my sadness, re: Objective C.
Beauty is subjective. For me, an Objective-C class is beautiful if it is readable (I know what it is supposed to do) and maintainable (I can see what parts are responsible for doing what). I also don't like to be thrown out of reading code by an unfamiliar idiom. Sort of like when you are reading a book and you read something that takes you out of the immersion and reminds you that you are reading.
You'll probably get lots of different, mutually exclusive advice, but here are my thoughts.
Nothing wrong with private methods being in a private category. That's what it is there for. If you don't like the declarations clogging up the file either use code folding in the IDE, or have your extensions as a category in a different file.
Group related methods together and mark them with #pragma mark statements
Whatever code layout you use, consistency is important. Take a few minutes and write your own guidelines (here are mine) so if you forget what you are supposed to be doing you have a reference.
The controller doesn't have to be the delegate and datasource you can always have other classes for these.
Use descriptive names for methods and properties. Yes, you may document them, but you can't see documentation when Xcode applies code completion, where well named methods and properties pay off. Also, code comments get stale if they aren't updated while the code itself changes.
Don't try and write clever code. You might think that it's better to chain a sequence of method calls on one line, but the compiler is better at optimising than you might think. It's okay to use temporary variables to hold values (mostly these are just pointers anyway, so relatively small) if it improves readability. Write code for humans to read.
DRY applies to Objective-C as much as other languages. Don't be worried about refactoring code into more methods. There is nothing wrong with having lots of methods as long as they are useful.
The very first thing I do even before implementing class or method is to ask: "How would I want to use this from the outside?"
I never ever, never begin by writing the internals of my classes and methods first. By starting of with an elegant public API the internals tend to become elegant for free, and if they don't then the ugliness is at least contained to a single method or class, and not allowed to pollute the rest of the code with it's smell.
There are many design patterns out there, two decades of coding have taught me that the only pattern that stand the test of time is: KISS. Keep It Simple Stupid.
Some general rules of thumb, for any language or environment:
Follow your gut feeling over any advice you have read or heard!
Bail out early!
If needed, verify inputs early and bail out fast! Less cleanup to do.
Never add something to your code that you do not use.
An option for "reverse" might feel like something nice to have down the road.
In that case add it down the road! Do not waste time adding complexity you do not need.
Method names should describe what is done, never how it is done.
Methods should be allowed to change their implementation without changing their name as long as the result is the same.
If you can not understand what a method does from it's name then change the name!
If the how part is complex enough, then use comments to describe your implementation.
Do not fear the singletons!
If your app only have one data model, then it is a singleton!
Passing around a single variable all over the place is just pretending it is something else but a singleton and adding complexity as bonus.
Plan for failures from the start.
Always use for doFoo:error instead of doFoo: from the start.
Create nice NSError instances with end user readable localized descriptions from the start.
It is a major pain to retrofit error handling/messages to a large existing app.
And there will always be errors if you have users and IO involved!
Cocoa/Objective-C is Object* Oriented, not **Class Oriented as most of the popular kids out there that claim to be OOP.
Do not introduce a dumb value class with only properties, a class without methods performing actual work could just as well be a struct.
Let your objects be intelligent! Why add a whole new FooParser class if a fooFromString: method on Foo is all you need?
In Cocoa what you can do is always more important than what you are.
Do not introduce a protocol if a target/action can do.
Do not verify that instances conforms to protocols, is a kind of class, that is up to the compiler.
My 2 cents:
Properties are usually better than old-style getter+setter. Even if you use #dynamic properties - declare them with #property, this is way more informative and shorter.
I personally don't simulate "private" methods for classes. Yes, I can write a category somewhere in the .m(m) file, but since Obj-C has no pure way to declare a private method - why should I invent one? Anyway, even if you really need something like that - declare a separate "MyClassPrivate.h" with a category and include it in the .m(m) files to avoid duplicating the declarations.
Binding. Binding for most Controller <-> UI relations, use transformers, formatters, just don't write methods to read/write controls values manually. It makes code look like something from MFC era.
C++, a lot of code look much better and shorter when written in C++. Since compiler understands C++ classes it's a good point for refactoring, especially when working will a low-level code.
I usually split big controllers. Something more than 500 lines of code is a good candidate for refactoring for me. For instance, I have a document window controller, since some version of the app it extends with image importing/exporting options. Controller grows up to 1.000 lines where 1/2 is the "image stuff". That's a "trigger" for me to make an ImageStuffController, instantiate it in the NIB and put all image-relative code in there.
All above make it easier for me to maintain my code. For a huge projects, where splitting the controllers and classes to keep 'em small results big number of files, I usually try to extract some code into a framework. For example, if a big part of the app is communicating with external web-services, there is usually a straight way to extract a MyWebServices.framework from the main app.
When do you encourage programming against an interface and not directly to a concrete class?
A guideline that I follow is to create abstractions whenever code requires to cross a logical/physical boundary, most especially when infrastructure-related concerns are involved.
Another checkpoint would be if a dependency will likely change in the future, due to possible additional concerns code (such as caching, transactional awareness, invoking a webservice instead of in-process execution) or if such dependencies have direct references to infrastructure integration points.
If code depends on something that does not require control to cross a logical/physical boundary, I more or less don't create abstractions to interact with those.
Am I missing anything?
Also, use interfaces when
Multiple objects will need to be acted upon in a particular fashion, but are not fundamentally related. Perhaps many of your business objects access a particular utility object, and when they do they need to give a reference of themselves to that utility object so the utility object can call a particular method. Have that method in an interface and pass that interface to that utility object.
Passing around interfaces as parameters can be very helpful in unit testing. Even if you have just one type of object that sports a particular interface, and hence don't really need a defined interface, you might define/implement an interface solely to "fake" that object in unit tests.
related to the first 2 bullets, check out the Observer pattern and the Dependency Injection. I'm not saying to implement these patterns, but they illustrate types of places where interfaces are really helpful.
Another twist on this is for implementing a couple of the SOLID Principals, Open Closed principal and the Interface Segregation principle. Like the previous bullet, don't get stressed about strictly implementing these principals everywhere (right away at least), but use these concepts to help move your thinking away from just what objects go where to thinking more about contracts and dependency
In the end, let's not make it too complicated: we're in a strongly typed world in .NET. If you need to call a method or set a property but the object you're passing/using could be fundamentally different, use an interface.
I would add that if your code is not going to be referenced by another library (for a while at least), then the decision of whether to use an interface in a particular situation is one that you can responsibly put off. The "extract interface" refactoring is easy to do these days. In my current project, I've got an object being passed around that I'm thinking maybe I should switch to an interface; I'm not stressing about it.
Interfaces abstraction are convenient when doing unit test. It helps for mocking test objects. It very useful in TDD for developing without actually using data from your database.
If you don't need any features of the class that aren't found in the Interface...then why not always prefer the Interface implementation?
It will make your code easier to modify in the future and easier to test (mocking).
you have the right idea, already. i would only add a couple of notes to this...
first, abstraction does not mean 'interface'. for example, a "connection string" is an abstraction, even though it's just a string... it's not about the 'type' of the thing in question, it's about the intention of use for that thing.
and secondly, if you are doing test automation of any kind, look for the pain and friction that are exposed by writing the tests. if you find yourself having to set up too many external conditions for a test, it's a sign that you need a better abstraction between the thing your testing and the things it interacts with.
I think you've said it pretty well. Much of this will be a stylistic thing. There are open source projects I've looked at where everything has an interface and an implementation, and it's kind of frustrating, but it might make iterative development a little easier, since any objects implementation can break but dummies will still work. But honestly, I can dummy any class that doesn't overuse the final keyword by inheritance.
I would add to your list this: anything which can be thought of as a black box should be abstracted. This includes some of the things you've mentioned, but it also includes hairy algorithms, which are likely to have multiple useful implementations with different advantages for different situation.
Additionally, interfaces come in handy very often with composite objects. That's the only way something like java's swing library gets anything done, but it can also be useful for more mundane objects. (I personally like having an interface like ValidityChecker with ways to and-compose or or-compose subordinate ValidityCheckers.)
Most of the useful things that come with the Interface passing have been already said. However I would add:
implementing an interface to an object, or later multiple objects, FORCES all the implementers to follow an IDENTICAL pattern to implement contract with the object. This can be useful in case you have not so OOP-experienced-programmers actually writing the implementation code.
in some languages you can add attributes on the interface itself, which can be different from the actual object implementation attribute as sense and intent
I am often in a situation where I have a concept represented by an interface or class, and then I have a series of subclasses/subinterfaces which extend it.
For example:
A generic "DoiGraphNode"
A "DoiGraphNode" representing a resource
A "DoiGraphNode" representing a Java resource
A "DoiGraphNode" with an associated path, etc., etc.
I can think of three naming conventions, and would appreciate comments on how to choose.
Option 1: Always start with the name of the concept.
Thus: DoiGraphNode, DoiGraphNodeResource, DoiGraphNodeJavaResource, DoiGraphNodeWithPath, etc.
Pro: It is very clear what I am dealing with, it is easy to see all the options I have
Con: Not very natural? Everything looks the same?
Option 2: Put the special stuff in the beginning.
Thus: DoiGraphNode, ResourceDoiGraphNode, JavaResourceDoiGraphNode, PathBaseDoiGraphNode,
etc., etc.
Pro: It is very clear when I see it in the code
Con: Finding it could be difficult, especially if I don't remember the name, lack of visual consistency
Option 3: Put the special stuff and remove some of the redundant text
Thus: DoiGraphNode, ResourceNode, JavaResourceNode, GraphNodeWithPath
Pro: Not that much to write and read
Con: Looks like cr*p, very inconsistent, may conflict with other names
Name them for what they are.
If naming them is hard or ambiguous, it's often a sign that the Class is doing too much (Single Responsibility Principle).
To avoid naming conflicts, choose your namespaces appropriately.
Personnally, I'd use 3
Use whatever you like, it's a subjective thing. The important thing is to make clear what each class represents, and the names should be such that the inheritance relationships make sense. I don't really think it's all that important to encode the relationships in the names, though; that's what documentation is for (and if your names are appropriate for the objects, people should be able to make good guesses as to what inherits from what).
For what it's worth, I usually use option 3, and from my experience looking at other people's code option 2 is probably more prevalent than option 1.
You could find some guidance in a coding standards document, for example there is the IDesign document for C# here.
Personally, I prefer option 2. This is generally the way the .NET Framework names its objects. For instance look at attribute classes. They all end in Attribute (TestMethodAttribute). The same goes for EventHandlers: OnClickEventHandler is a recommended name for an event handler that handles the Click event.
I usually try to follow this in designing my own code and interfaces. Thus an IUnitWriter produces a StringUnitWriter and a DataTableUnitWriter. This way I always know what their base class is and it reads more naturally. Self-documenting code is the end-goal for all agile developers so it seems to work well for me!
I usually name similar to option 1, especially when the classes will be used polymophically.
My reasoning is that the most important bit of information is listed first.
(I.e. the fact that the subclass is basically what the ancestor is,
with (usually) extensions 'added').
I like this option also because when sorting lists of class names,
the related classes will be listed together.
I.e. I usually name the translation unit (file name) the same as
the class name so related class files will naturally be listed together.
Similarly this is useful with incremental search.
Although I tended to use option 2 earlier in my programming career, I avoid it now because as you say it is 'inconsistant' and do not seem very orthogonal.
I often use option 3 when the subclass provides substantial extension or specification, or if the names would be rather long.
For example, my file system name classes are derived from String
but they greatly extend the String class and have a significantly different
use/meaning:
Directory_entry_name derived from String adds extensive functionality.
File_name derived from Directory_entry_name has rather specialized functions.
Directory_name derived from Directory_entry_name also has rather specialized functions.
Also along with option 1, I usually use an unqualified name for an interface class.
For example I might have a class interence chain:
Text (an interface)
Text_abstract (abstract (base) generalization class)
Text_ASCII (concrete class specific for ASCII coding)
Text_unicode (concrete class specific for unicode coding)
I rather like that the interface and the abstract base class automatically appear first in the sorted list.
Option three more logically follows from the concept of inheritance. Since you're specializing the interface or class, the name should show that it's no longer using the base implementation (if one exists).
There are a multitude of tools to see what a class inherits from, so a concise name indicating the real function of the class will go farther than trying to pack too much type information into the name.
I must confess I'm somewhat of an OOP skeptic. Bad pedagogical and laboral experiences with object orientation didn't help. So I converted into a fervent believer in Visual Basic (the classic one!).
Then one day I found out C++ had changed and now had the STL and templates. I really liked that! Made the language useful. Then another day MS decided to apply facial surgery to VB, and I really hated the end result for the gratuitous changes (using "end while" instead of "wend" will make me into a better developer? Why not drop "next" for "end for", too? Why force the getter alongside the setter? Etc.) plus so much Java features which I found useless (inheritance, for instance, and the concept of a hierarchical framework).
And now, several years afterwards, I find myself asking this philosophical question: Is inheritance really needed?
The gang-of-four say we should favor object composition over inheritance. And after thinking of it, I cannot find something you can do with inheritance you cannot do with object aggregation plus interfaces. So I'm wondering, why do we even have it in the first place?
Any ideas? I'd love to see an example of where inheritance would be definitely needed, or where using inheritance instead of composition+interfaces can lead to a simpler and easier to modify design. In former jobs I've found if you need to change the base class, you need to modify also almost all the derived classes for they depended on the behaviour of parent. And if you make the base class' methods virtual... then not much code sharing takes place :(
Else, when I finally create my own programming language (a long unfulfilled desire I've found most developers share), I'd see no point in adding inheritance to it...
Really really short answer: No. Inheritance is not needed because only byte code is truly needed. But obviously, byte code or assemble is not a practically way to write your program. OOP is not the only paradigm for programming. But, I digress.
I went to college for computer science in the early 2000s when inheritance (is a), compositions (has a), and interfaces (does a) were taught on an equal footing. Because of this, I use very little inheritance because it is often suited better by composition. This was stressed because many of the professors had seen bad code (along with what you have described) because of abuse of inheritance.
Regardless of creating a language with or without inheritances, can you create a programming language which prevents bad habits and bad design decisions?
I think asking for situations where inheritance is really needed is missing the point a bit. You can fake inheritance by using an interface and some composition. This doesnt mean inheritance is useless. You can do anything you did in VB6 in assembly code with some extra typing, that doesn't mean VB6 was useless.
I usually just start using an interface. Sometimes I notice I actually want to inherit behaviour. That usually means I need a base class. It's that simple.
Inheritance defines an "Is-A" relationship.
class Point( object ):
# some set of features: attributes, methods, etc.
class PointWithMass( Point ):
# An additional feature: mass.
Above, I've used inheritance to formally declare that PointWithMass is a Point.
There are several ways to handle object P1 being a PointWithMass as well as Point. Here are two.
Have a reference from PointWithMass object p1 to some Point object p1-friend. The p1-friend has the Point attributes. When p1 needs to engage in Point-like behavior, it needs to delegate the work to its friend.
Rely on language inheritance to assure that all features of Point are also applicable to my PointWithMass object, p1. When p1 needs to engage in Point-like behavior, it already is a Point object and can just do what needs to be done.
I'd rather not manage the extra objects floating around to assure that all superclass features are part of a subclass object. I'd rather have inheritance to be sure that each subclass is an instance of it's own class, plus is an instance of all superclasses, too.
Edit.
For statically-typed languages, there's a bonus. When I rely on the language to handle this, a PointWithMass can be used anywhere a Point was expected.
For really obscure abuse of inheritance, read about C++'s strange "composition through private inheritance" quagmire. See Any sensible examples of creating inheritance without creating subtyping relations? for some further discussion on this. It conflates inheritance and composition; it doesn't seem to add clarity or precision to the resulting code; it only applies to C++.
The GoF (and many others) recommend that you only favor composition over inheritance. If you have a class with a very large API, and you only want to add a very small number of methods to it, leaving the base implementation alone, I would find it inappropriate to use composition. You'd have to re-implement all of the public methods of the encapsulated class to just return their value. This is a waste of time (programmer and CPU) when you can just inherit all of this behavior, and spend your time concentrating on new methods.
So, to answer your question, no you don't absolutely need inheritance. There are, however, many situations where it's the right design choice.
The problem with inheritance is that it conflates the issue of sub-typing (asserting an is-a relationship) and code reuse (e.g., private inheritance is for reuse only).
So, no it's an overloaded word that we don't need. I'd prefer sub-typing (using the 'implements' keyword) and import (kinda like Ruby does it in class definitions)
Inheritance lets me push off a whole bunch of bookkeeping onto the compiler because it gives me polymorphic behavior for object hierarchies that I would otherwise have to create and maintain myself. Regardless of how good a silver bullet OOP is, there will always be instances where you want to employ a certain type of behavior because it just makes sense to do. And ultimately, that's the point of OOP: it makes a certain class of problems much easier to solve.
The downsides of composition is that it may disguise the relatedness of elements and it may be harder for others to understand. With,say, a 2D Point class and the desire to extend it to higher dimensions, you would presumably have to add (at least) Z getter/setter, modify getDistance(), and maybe add a getVolume() method. So you have the Objects 101 elements: related state and behavior.
A developer with a compositional mindset would presumably have defined a getDistance(x, y) -> double method and would now define a getDistance(x, y, z) -> double method. Or, thinking generally, they might define a getDistance(lambdaGeneratingACoordinateForEveryAxis()) -> double method. Then they would probably write createTwoDimensionalPoint() and createThreeDimensionalPoint() factory methods (or perhaps createNDimensionalPoint(n) ) that would stitch together the various state and behavior.
A developer with an OO mindset would use inheritance. Same amount of complexity in the implementation of domain characteristics, less complexity in terms of initializing the object (constructor takes care of it vs. a Factory method), but not as flexible in terms of what can be initialized.
Now think about it from a comprehensibility / readability standpoint. To understand the composition, one has a large number of functions that are composed programmatically inside another function. So there's little in terms of static code 'structure' (files and keywords and so forth) that makes the relatedness of Z and distance() jump out. In the OO world, you have a great big flashing red light telling you the hierarchy. Additionally, you have an essentially universal vocabulary to discuss structure, widely known graphical notations, a natural hierarchy (at least for single inheritance), etc.
Now, on the other hand, a well-named and constructed Factory method will often make explicit more of the sometimes-obscure relationships between state and behavior, since a compositional mindset facilitates functional code (that is, code that passes state via parameters, not via this ).
In a professional environment with experienced developers, the flexibility of composition generally trumps its more abstract nature. However, one should never discount the importance of comprehensibility, especially in teams that have varying degrees of experience and/or high levels of turnover.
Inheritance is an implementation decision. Interfaces almost always represent a better design, and should usually be used in an external API.
Why write a lot of boilerplate code forwarding method calls to a composed member object when the compiler will do it for you with inheritance?
This answer to another question summarises my thinking pretty well.
Does anyone else remember all of the OO-purists going ballistic over the COM implementation of "containment" instead of "inheritance?" It achieved essentially the same thing, but with a different kind of implementation. This reminds me of your question.
I strictly try to avoid religious wars in software development. ("vi" OR "emacs" ... when everybody knows its "vi"!) I think they are a sign of small minds. Comp Sci Professors can afford to sit around and debate these things. I'm working in the real world and could care less. All of this stuff are simply attempts at giving useful solutions to real problems. If they work, people will use them. The fact that OO languages and tools have been commercially available on a wide scale for going on 20 years is a pretty good bet that they are useful to a lot of people.
There are a lot of features in a programming language that are not really needed. But they are there for a variety of reasons that all basically boil down to reusability and maintainability.
All a business cares about is producing (quality of course) cheaply and quickly.
As a developer you help do this is by becoming more efficient and productive. So you need to make sure the code you write is easily reusable and maintainable.
And, among other things, this is what inheritance gives you - the ability to reuse without reinventing the wheel, as well as the ability to easily maintain your base object without having to perform maintenance on all similar objects.
There's lots of useful usages of inheritance, and probably just as many which are less useful. One of the useful ones is the stream class.
You have a method that should be able stream data. By using the stream base class as input to the method you ensure that your method can be used to write to many kinds of streams without change. To the file system, over the network, with compression, etc.
No.
for me, OOP is mostly about encapsulation of state and behavior and polymorphism.
and that is. but if you want static type checking, you'll need some way to group different types, so the compiler can check while still allowing you to use new types in place of another, related type. creating a hierarchy of types lets you use the same concept (classes) for types and for groups of types, so it's the most widely used form.
but there are other ways, i think the most general would be duck typing, and closely related, prototype-based OOP (which isn't inheritance in fact, but it's usually called prototype-based inheritance).
Depends on your definition of "needed". No, there is nothing that is impossible to do without inheritance, although the alternative may require more verbose code, or a major rewrite of your application.
But there are definitely cases where inheritance is useful. As you say, composition plus interfaces together cover almost all cases, but what if I want to supply a default behavior? An interface can't do that. A base class can. Sometimes, what you want to do is really just override individual methods. Not reimplement the class from scratch (as with an interface), but just change one aspect of it. or you may not want all members of the class to be overridable. Perhaps you have only one or two member methods you want the user to override, and the rest, which calls these (and performs validation and other important tasks before and after the user-overridden methods) are specified once and for all in the base class, and can not be overridden.
Inheritance is often used as a crutch by people who are too obsessed with Java's narrow definition of (and obsession with) OOP though, and in most cases I agree, it's the wrong solution, as if the deeper your class hierarchy, the better your software.
Inheritance is a good thing when the subclass really is the same kind of object as the superclass. E.g. if you're implementing the Active Record pattern, you're attempting to map a class to a table in the database, and instances of the class to a row in the database. Consequently, it is highly likely that your Active Record classes will share a common interface and implementation of methods like: what is the primary key, whether the current instance is persisted, saving the current instance, validating the current instance, executing callbacks upon validation and/or saving, deleting the current instance, running a SQL query, returning the name of the table that the class maps to, etc.
It also seems from how you phrase your question that you're assuming that inheritance is single but not multiple. If we need multiple inheritance, then we have to use interfaces plus composition to pull off the job. To put a fine point about it, Java assumes that implementation inheritance is singular and interface inheritance can be multiple. One need not go this route. E.g. C++ and Ruby permit multiple inheritance for your implementation and your interface. That said, one should use multiple inheritance with caution (i.e. keep your abstract classes virtual and/or stateless).
That said, as you note, there are too many real-life class hierarchies where the subclasses inherit from the superclass out of convenience rather than bearing a true is-a relationship. So it's unsurprising that a change in the superclass will have side-effects on the subclasses.
Not needed, but usefull.
Each language has got its own methods to write less code. OOP sometimes gets convoluted, but I think that is the responsability of the developers, the OOP platform is usefull and sharp when it is well used.
I agree with everyone else about the necessary/useful distinction.
The reason I like OOP is because it lets me write code that's cleaner and more logically organized. One of the biggest benefits comes from the ability to "factor-up" logic that's common to a number of classes. I could give you concrete examples where OOP has seriously reduced the complexity of my code, but that would be boring for you.
Suffice it to say, I heart OOP.
Absolutely needed? no,
But think of lamps. You can create a new lamp from scratch each time you make one, or you can take properties from the original lamp and make all sorts of new styles of lamp that have the same properties as the original, each with their own style.
Or you can make a new lamp from scratch or tell people to look at it a certain way to see the light, or , or, or
Not required, but nice :)
Thanks to all for your answers. I maintain my position that, strictly speaking, inheritance isn't needed, though I believe I found a new appreciation for this feature.
Something else: In my job experience, I have found inheritance leads to simpler, clearer designs when it's brought in late in the project, after it's noticed a lot of the classes have much commonality and you create a base class. In projects where a grand-schema was created from the very beginning, with a lot of classes in an inheritance hierarchy, refactoring is usually painful and dificult.
Seeing some answers mentioning something similar makes me wonder if this might not be exactly how inheritance's supposed to be used: ex post facto. Reminds me of Stepanov's quote: "you don't start with axioms, you end up with axioms after you have a bunch of related proofs". He's a mathematician, so he ought to know something.
The biggest problem with interfaces is that they cannot be changed. Make an interface public, then change it (add a new method to it) and break million applications all around the world, because they have implemented your interface, but not the new method. The app may not even start, a VM may refuse to load it.
Use a base class (not abstract) other programmers can inherit from (and override methods as needed); then add a method to it. Every app using your class will still work, this method just won't be overridden by anyone, but since you provide a base implementation, this one will be used and it may work just fine for all subclasses of your class... it may also cause strange behavior because sometimes overriding it would have been necessary, okay, might be the case, but at least all those million apps in the world will still start up!
I rather have my Java application still running after updating the JDK from 1.6 to 1.7 with some minor bugs (that can be fixed over time) than not having it running it at all (forcing an immediate fix or it will be useless to people).
//I found this QA very useful. Many have answered this right. But i wanted to add...
1: Ability to define abstract interface - E.g., for plugin developers. Of course, you can use function pointers, but this is better and simpler.
2: Inheritance helps model types very close to their actual relationships. Sometimes a lot of errors get caught at compile time, because you have the right type hierarchy. For instance, shape <-- triangle (lets say there is a lot of code to be reused). You might want to compose triangle with a shape object, but shape is an incomplete type. Inserting dummy implementations like double getArea() {return -1;} will do, but you are opening up room for error. That return -1 can get executed some day!
3: void func(B* b); ... func(new D()); Implicit type conversion gives a great notational convenience since Derived is Base. I remember having read Straustrup saying that he wanted to make classes first class citizens just like fundamental data types (hence overloading operators etc). Implicit conversion from Derived to Base, behaves just like an implicit conversion from a data type to broader compatible one (short to int).
Inheritance and Composition have their own pros and cons.
Refer to this related SE question on pros of inheritance and cons of composition.
Prefer composition over inheritance?
Have a look at the example in this documentation link:
The example shows different use cases of overriding by using inheritance as a mean to achieve polymorphism.
In the following, inheritance is used to present a particular property for all of several specific incarnations of the same type thing. In this case, the GeneralPresenation has a properties that are relevant to all "presentation" (the data passed to an MVC view). The Master Page is the only thing using it and expects a GeneralPresentation, though the specific views expect more info, tailored to their needs.
public abstract class GeneralPresentation
{
public GeneralPresentation()
{
MenuPages = new List<Page>();
}
public IEnumerable<Page> MenuPages { get; set; }
public string Title { get; set; }
}
public class IndexPresentation : GeneralPresentation
{
public IndexPresentation() { IndexPage = new Page(); }
public Page IndexPage { get; set; }
}
public class InsertPresentation : GeneralPresentation
{
public InsertPresentation() {
InsertPage = new Page();
ValidationInfo = new PageValidationInfo();
}
public PageValidationInfo ValidationInfo { get; set; }
public Page InsertPage { get; set; }
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
Improve this question
When designing a new system or getting your head around someone else's code, what are some tell tale signs that something has gone wrong in the design phase? Are there clues to look for on class diagrams and inheritance hierarchies or even in the code itself that just scream for a design overhaul, particularly early in a project?
The things that mostly stick out for me are "code smells".
Mostly I'm sensitive to things that go against "good practice".
Things like:
Methods that do things other than what you'd think from the name (eg: FileExists() that silently deletes zero byte files)
A few extremely long methods (sign of an object wrapper around a procedure)
Repeated use of switch/case statements on the same enumerated member (sign of sub-classes needing extraction)
Lots of member variables that are used for processing, not to capture state (might indicate need to extract a method object)
A class that has lots of responsibilities (violation of Single Repsonsibility principle)
Long chains of member access (this.that is fine, this.that.theOther is fine, but my.very.long.chain.of.member.accesses.for.a.result is brittle)
Poor naming of classes
Use of too many design patterns in a small space
Working too hard (rewriting functions already present in the framework, or elsewhere in the same project)
Poor spelling (anywhere) and grammar (in comments), or comments that are simply misleading
I'd say the number one rule of poor OO design (and yes I've been guilty of it too many times!) is:
Classes that break the Single
Responsibility Principle (SRP) and
perform too many actions
Followed by:
Too much inheritance instead of
composition, i.e. Classes that
derive from a sub-type purely so
they get functionality for free.
Favour Composition over Inheritance.
Impossible to unit test properly.
Anti-patterns
Software design anti-patterns
Abstraction inversion : Not exposing implemented functionality required by users, so that they re-implement it using higher level functions
Ambiguous viewpoint: Presenting a model (usually OOAD) without specifying its viewpoint
Big ball of mud: A system with no recognizable structure
Blob: Generalization of God object from object-oriented design
Gas factory: An unnecessarily complex design
Input kludge: Failing to specify and implement handling of possibly invalid input
Interface bloat: Making an interface so powerful that it is extremely difficult to implement
Magic pushbutton: Coding implementation logic directly within interface code, without using abstraction.
Race hazard: Failing to see the consequence of different orders of events
Railroaded solution: A proposed solution that while poor, is the only one available due to poor foresight and inflexibility in other areas of the design
Re-coupling: Introducing unnecessary object dependency
Stovepipe system: A barely maintainable assemblage of ill-related components
Staralised schema: A database schema containing dual purpose tables for normalised and datamart use
Object-oriented design anti-patterns
Anemic Domain Model: The use of domain model without any business logic which is not OOP because each object should have both attributes and behaviors
BaseBean: Inheriting functionality from a utility class rather than delegating to it
Call super: Requiring subclasses to call a superclass's overridden method
Circle-ellipse problem: Subtyping variable-types on the basis of value-subtypes
Empty subclass failure: Creating a class that fails the "Empty Subclass Test" by behaving differently from a class derived from it without modifications
God object: Concentrating too many functions in a single part of the design (class)
Object cesspool: Reusing objects whose state does not conform to the (possibly implicit) contract for re-use
Object orgy: Failing to properly encapsulate objects permitting unrestricted access to their internals
Poltergeists: Objects whose sole purpose is to pass information to another object
Sequential coupling: A class that requires its methods to be called in a particular order
Singletonitis: The overuse of the singleton pattern
Yet Another Useless Layer: Adding unnecessary layers to a program, library or framework. This became popular after the first book on programming patterns.
Yo-yo problem: A structure (e.g., of inheritance) that is hard to understand due to excessive fragmentation
This question makes the assumption that object-oriented means good design. There are cases where another approach is much more appropriate.
One smell is objects having hard dependencies/references to other objects that aren't a part of their natural object hierarchy or domain related composition.
Example: Say you have a city simulation. If the a Person object has a NearestPostOffice property you are probably in trouble.
One thing I hate to see is a base class down-casting itself to a derived class. When you see this, you know you have problems.
Other examples might be:
Excessive use of switch statements
Derived classes that override everything
In my view, all OOP code degenerates to procedural code over a sufficiently long time span.
Granted, if you read my most recent question, you might understand why I am a little jaded.
The key problem with OOP is that it doesn't make it obvious that your object construction graph should be independent of your call graph.
Once you fix that problem, OOP actually starts to make sense. The problem is that very few teams are aware of this design pattern.
Here's a few:
Circular dependencies
You with property XYZ of a base class wasn't protected/private
You wish your language supported multiple inheritance
Within a long method, sections surrounded with #region / #endregion - in almost every case I've seen, that code could easily be extracted into a new method OR needed to be refactored in some way.
Overly-complicated inheritance trees, where the sub-classes do very different things and are only tangentially related to one another.
Violation of DRY - sub-classes that each override a base method in almost exactly the same way, with only a minor variation. An example: I recently worked on some code where the subclasses each overrode a base method and where the only difference was a type test ("x is ThisType" vs "x is ThatType"). I implemented a method in the base that took a generic type T, that it then used in the test. Each child could then call the base implementation, passing the type it wanted to test against. This trimmed about 30 lines of code from each of 8 different child classes.
Duplicate code = Code that does the same thing...I think in my experience this is the biggest mistake that can occur in OO design.
Objects are good create a gazillion of them is a bad OO design.
Having all you objects inherit some base utility class just so you can call your utility methods without having to type so much code.
Find a programmer who is experienced with the code base. Ask them to explain how something works.
If they say "this function calls that function", their code is procedural.
If they say "this class interacts with that class", their code is OO.
Following are most prominent features of a bad design:
Rigidity
Fragility
Immobility
Take a look at The Dependency Inversion Principle
When you don't just have a Money\Amount class but a TrainerPrice class, TablePrice class, AddTablePriceAction class and so on.
IDE Driven Development or Auto-Complete development. Combined with extreme strict typing is a perfect storm.
This is where you see what could be a lot of what could be variable values become class names and method names as well as the gratuitous use of classes in general. You'll also see things like all primitives becoming objects. All literals as classes. Function parameters as classes. Then conversion methods everywhere. You'll also see things like a class wrapping another delivering a subset of methods to another class inclusive of only the ones it needs at present.
This creates the possibility to generate an near infinite amount of code which is great if you have billable hours. When variables, contexts, properties and states get unrolled into hyper explicit and overly specific classes then this creates an exponential cataclysm as sooner or later those things multiply. Think of it like [a, b] x [x, y]. This can be further compounded by an attempt to create a full fluent interface as well as adhere to as many design patterns as possible.
OOP languages are not as polymorphic as some loosely typed languages. Loosely typed languages often offer runtime polymorphism in shallow syntax that static analysis can't handle.
In OOP you might see forms of repetition hard to automatically detect that could be turned into more dynamic code using maps. Although such languages are less dynamic you can achieve dynamic features with some extra-work.
The trade of here is that you save thousands (or millions) of lines of code while potentially loosing IDE features and static analysis. Performance can go either way. Run time polymorphism can often be converted to generated code. However in some cases the space is so huge that anything other than runtime polymorphism is impossible.
Problems are a lot more common with OOP languages lacking generics and when OOP programmers try to strictly type dynamic loosely typed language.
What happens without generics is where you should have A for X = [Q, W, E] and Y = [R, T, Y] you instead see [AQR, AQT, AQY, AWR, AWT, AWY, AER, AET, AEY]. This is often due to fear or using typeless or passing the type as a variable for loosing IDE support.
Traditionally loosely typed languages are made with a text editor rather than an IDE and the advantage lost through IDE support is often gained in other ways such as organising and structuring code such that it is navigable.
Often IDEs can be configured to understand your dynamic code (and link into it) but few properly support it in a convenient manner.
Hint: The context here is OOP gone horrifically wrong in PHP where people using simple OOP Java programming traditionally have tried to apply that to PHP which even with some OOP support is a fundamentally different type of language.
Designing against your platform to try to turn it into one your used to, designing to cater to an IDE or other tools, designing to cater to supporting Unit Tests, etc should all ring alarm bells because it's a significant deviation away from designing working software to solve a given category of problems or a given feature set.