5 ms·
Why you should never ever ever have Managers in your class name
- franzwong 14y agoI would not follow the rule strictly if I find that people working with me understand that a class with name XXXManager more than a class called XXX.
- Evbn 14y agoDon't give that coder a Manager class. Coders hate managers.
- sgpl 14y agoI generally disagree with 'never ever' statements because they apply a blanket clause to a particular issue and tend to be from the perspective of someone who has experienced that problem in the past. As a relatively new programmer, this post was pretty insightful. Thanks. Sometimes I learn better by making the mistakes and learning not to repeat them; that can be pretty annoying for others that have to work with my code I guess. Most mistakes I've made while programming are non-fatal/non-critical, but they do add up and refactoring perhaps helps with that. I think pair programming further alleviates such issues? So the lesson learnt is that I should be more mindful of how I name classes/methods, which I honestly haven't paid much attention to in the past.
- twoodfin 14y agoThere are only two hard problems in Computer Science: cache invalidation and naming things. -- Phil Karlton There should be a short list of words never to appear in names. "Manager" is certainly one. I nominate "Handler" as another.
- matwood 14y agoFrom the Android SDK :) http://developer.android.com/reference/android/os/Handler.html http://developer.android.com/reference/android/os/Handler.ht...
- dack 14y agoMan, as much as I like the idea of Android, the SDK trips me up so often!
- bleair 14y agoThere are only 2 hard problems in computer science, caching, and naming things, and off by one errors
- Evbn 14y agoUnambiguous syntax is also a hard problem, it now appears.
- nailer 14y agoMore meaningless words: - system. Everything is a system. - data. Everything that isn't executable is data.
- cpeterso 14y agoThe class name modifier that irks me is "Base", as in BaseWidget or ConnectionBase. Just call them a Widget or Connection! :)
- yen223 14y agoBaseWidget is useful when it's an abstract class, to differentiate it from the actual implementations WidgetA and WidgetB.
- cpeterso 14y agoWouldn't a "Widget" abstract class name also be differentiated from "WidgetA" and "WidgetB" implementations? Then APIs could take parameters of type Widget instead of type BaseWidget. "Widget" is a shorter, cleaner name and avoids documenting implementation details like names such as "BaseWidget" or "AbstractWidget".
- sha90 14y agoThere are certain ... linguistic... reasons why Base appears in class names. It's important to understand the subtlety. In certain languages, especially those with packages or namespaces, you'll likely have a namespace Foo::Bar::Widgets where you put your WhateverWidgetWhatever classes. The package foo.bar.widgets.widget, or namespace Foo::Bar::Widgets::Widget, can look weird to some; it's also longer / less predictable, so you could potentially see them simply be called Foo::Bar::Widget::Base, which avoids naming duplication, and allows developers to not have to worry about plural/singular names.
- dack 14y agoUsually, I want to make the name of my interface the cleanest possible name. In that case, my interface would be named "Widget". Then, if it makes sense, I might have a partial implementation that works for many cases - I would probably call that WidgetBase. Actual implementations of the widget would try to have a name related to what makes them different than the others - maybe Button, TextBox, etc. Those implementations might inherit from WidgetBase if it makes sense, or just implement the interface. At any rate, WidgetBase is only ever referenced by subclasses - the users of the widget code would either depend on "Button" or "TextBox" specficially, or the "Widget" interface for more generic handling. WidgetBase is really just there for convenience, and you could remove it if it turns out not to be as useful as you thought.
- MartinCron 14y agoI personally don't like "Helper". Shouldn't every class be helpful?
- deleted 14y ago[deleted]
- Jare 14y agoNaming things is only hard if you are trying to be consistent across a large systems, or hoping that names will replace documentation and assumptions. If you are going to ban names, I nominate the entire index of the GoF book: Factory, Singleton, Command, Proxy, etc. all sort of convey an idea of the kind of stuff they probably do, but nothing truly precise about the details. Or I can just accept a rough meaning of the word, name my classes / modules / variables / etc reasonably and then rely on a coherent approach to design and documentation to provide with the details. - XXXManager: owns the lifetime of objects of class XXX and the relationships between them. - XXXHandler: responds to events relating to XXX. - XXXFactory: creates instances of the polymorphic type XXX - etc.
- swanson 14y agoJust make sure this logic doesn't leak out and pollute your whole codebase. Otherwise you will have that whole hairy mess of opening multiple async connections with auto-retries right in the middle of your business logic. Want to send a Shoutt? Well first, you need to new up a connection pool and setup the exponential back-off strategy... You should probably consider hiding all of that complexity behind an intention-revealing interface. Something like ConnectionManager - it will manage all the hairy connection internals and let you write cleaner code as your extend your app. Software Design is hard. :)
- chris_wot 14y agoHopefully this doesn't sound too dense, but what if whole point of the class is to manage connections? What exactly is meant to take it's place? It seems to me that the issue is that they named the class ConnectionManager when it should have been Connection. But then if you are doing connection pooling, and you need specific control over the Connection objects, then what would the harm be in delegating this to a ConnectionManager class, which manages a bunch of Connection objects?
- BIackSwan 14y agoYou can create a ConnectionPool class with the relevant logic to manage Connections. If you want multiple pools (which you might connect to different servers ;) ) you just instantiate multiple ConnectionPools. ConnectionPool makes you think of it as an actual object. ConnectionManager makes you think of this all encompassing thing that handles/manages anything that is Connection related.
- Evbn 14y agoYou mean "pool connections" not "manage connections".
- robryan 14y agoYou still might want a connection manager to contain your connection pools. Or even call it a messages or something, so at the relevant point in the code you just call a send function and aren't exposed to any underlying details of connections.
- Evbn 14y agoSpecifically, what is the class doing with those pools? "Managing" is vague.
- joe_the_user 14y agoThe Connection Manager in QT, for example, is not a Connection Pool. It's more of an interface to get at all the classes that represent real things within a connection process (requests, responses, active connections, etc). There is no information in the Connection Manager except system/process defaults. The Connection Manager would create connection pools if that is what's needed but it isn't Connection Pool any more than it is a connection. That said, I sympathize with the impulse that the term "manager" says there's something wrong in your OO design. It is simply that determining how to get around the problem is hard.
- Swannie 14y agoTL;DR: Don't name a class for a <thing>, <thing>Manager.
- rvasa 14y agoPeople use words (terms/names) to communicate. I am not sure if most developers think deeply about all this -- nor do they care, or want to care. My observation is that developers just do and mimic what they find commonly used in their environment. Very much like we learn and use English. So, if you are a Java developer and you take the API as your template -- then that is the vocabulary that seeps out.
- deleted 14y ago[deleted]
- deleted 14y ago[deleted]
- bridgeyman 14y agoWhew, good thing mine is called ConnectionController.
- Lagged2Death 14y agoIt makes me feel pretty dense to admit this, but I don't see the connection (ha) between this basic good advice (use short, precise, descriptive class names -- certain classes of names are a warning sign) and the famous "Kingdom of Nouns" essay the author is so eager to have us read. Because a "ThingManager" is still noun-style all the way, even if you rename it to "Thing."
- BIackSwan 14y agoThe "Kingdom of Nouns" essay is about the forceful enforcement of Nouns even when they aren't entirely necessary. As a consequence of this thinking, it has led to the rise of use of -Manager classes even when not required. More importantly, the acceptance in the developer community that its ok to define large number of classes with that name is just a bad influence. Noun style is not a bad thing at all. Its just that when you think of everything as Nouns that things go downhill (which lead to naming things -Managers, -Handlers etc).
- Lagged2Death 14y ago...when you think of everything as Nouns that things go downhill (which lead to naming things -Managers, -Handlers etc). Yeah, not seeing it. If I "think of everything as Nouns" then I might go with "Noun" or "NounManager" as a name - but they're both nouns, and I don't see how pointing that out helps. I completely agree with the point that "Manager" style classes are a warning sign that something could be usefully refactored. But if you're just going to refactor stuff into other nouns, and you're trapped in a noun-centric language anyway, I don't see any real connection between the advice on the one hand and the message about how trapped I am on the other.
- richardwhiuk 14y agoI think the more salient point here should actually be if you have a thingManager, you should almost certainly have a thing. From a external perspective, using a thingManager is likelier to be easier, but from an internal perspective, having both a thing and a thingManager will force you to think about putting the logic in the correct place.
- azov 14y agoThingManager is indeed a bad name, but I think the article is blurring the explanation with poorly chosen example. The example is more about wrong design than wrong name, there are certainly legitimate cases when you want a class that deals with multiple things. ThingManager is a bad metaphor for a class that follows single responsibility principle (http://en.wikipedia.org/wiki/Single_responsibility_principle http://en.wikipedia.org/wiki/Single_responsibility_principle). It encourages you to stuff too much into a class because managers do many things, and it's not always clear what exactly they do - almost anything can be thought of as some sort of "management". The real reason is mentioned two paragraphs from the end - the name is simply too ambiguous.
- unclebucknasty 14y agoI think there are times when you want a class to do multiple related things and encapsulating them in one place makes sense. And sometimes, the word "manager" is perfectly descriptive and sufficient. Take the DriverManager class from the JDK (JDBC). To me, it's always been a clean way to register JDBC drivers, get connections, etc. It is responsible for internally managing available driver classes and selecting the appropriate driver to use for a particular connection string. It manages all of this internally, and, from my perspective, it is well-named. I do think, like anything, the concept can be overused. But, I just don't agree with this kind of "never, ever use x in your class names or your code is evil" blanket statement.
- LoneWolf 14y agoI fail to see the problem of using manager in the name, what I see is a class that should have been renamed to connection extended etc if needed, and multiple instances created, then if needed, a ConnectionManager created to take care of them. The problem isn't the name but the person who instead of renaming it went with a monolithic approach.
- SilasX 14y agoI've heard it said that having any class name as [verb]-er is an OOP anti-pattern, as your objects shouldn't be simple nounifications of verbs.
- Evbn 14y agoThat rules of thumb is arbitrary attempt to make code more like fancy English. Why is "connection" OK but "connecter" bad?
- SilasX 14y agoIt's not the name per se that is the problem; the point is that an "-er" class is indicative that you're actually using a procedural rather than OO paradigm, and thus attempting to arbitrarily box up a bunch of actions into an object. Neither connection nor connector would be good, under this view, if it's just a thin package around an imperative program ("COBOL written in Java").
- samspot 14y agoTo me the purpose of ThingManager is perfectly clear--to manage miscellaneous or common functionality that doesn't belong in Thing. In our apps we call it ThingService, and I'm sure other groups have a different convention. For example, we're using a legacy codebase now where there is some complicated logic involved in managing attributes for products. ProductService is a singleton with no internal state that does things like removeAttribute(product, "foo") and serves other purposes. Before we introduced this pattern this kind of functionality was copy-pasted all around our controllers. In short, I don't see the harm in this convention. Perhaps Manager or Service is bland name, but it's immediately clear to our developers what it does, and if you want to see if something has been done before with products, you look in Product or ProductService.
- Evbn 14y agoYeah, Manager is a "code smell", but not a showstopper. Good workers don't need much managers.
- azov 14y ago> the purpose of ThingManager is perfectly clear--to manage miscellaneous or common functionality Ironic, isn't it? :) PS. Don't get me wrong - a Manager, or Util, or Helper is not the greatest crime against software design. The intention here is clear, functionality - no, not really. However engineering is about tradeoffs, and it is sometimes practical to have a dumping place for miscellaneous stuff. Just keep in mind that it is a "be careful" territory, those places do tend to turn into ugly and hairy mess over time.
- sha90 14y agoIt's not that it "doesn't belong in Thing", but rather, it can be performed by another entity. These are the same fundamental "responsibility" questions we struggle with in designing OO systems every day. When you have two or more entities collaborating on a responsibility, which one of them get the actual method? Incidentally, this is kind of what real life managers are for too, as much as we like to dislike them.
- craigching 14y agoClass names are pretty much meaningless to me. It's hard to name classes, so in my experience, I tend to look past them and understand the responsibilities of the class and pretty much ignore the name. If it's too hard to understand the class responsibilities without a lot of work, then the class is definitely poorly designed, most likely too complicated.
- gizmo686 14y agoThe problem is when someone is trying to browse the code. When things are well named, then it is much easier for someone unfamiliar with the code base to find their way around. I've done a fair amount of hacking around in open source projects. There are some projects where I can download the source code, know what I want to do going into it, and just do it. In other projects, when I am at a place I think is relevant to what I want to do, I have to dive deep into the programs abstraction layers just to see how certain objects and functions behave and what they do. Some of that is likely an unavoidable result of me needing to get to a rather core part of the code, but it seems like a lot of it has to do with the clarity of naming. If I need to know the precise behavior, I will generally look it up anyway, but I do not need to know the precise behavior of everything.
- blt 14y agoThis is basic stuff. It works fine until we realize that the app requires multiple simultaneous connections to the server. Now because you have a ConnectionManager, you go ahead and introduce an array inside the class which maintains the state of all the open connections to the server. No competent programmer would make this mistake solely because the class is called ConnectionManager.
- deleted 14y ago[deleted]
- hcarvalhoalves 14y agoThe problem is in OO, or rather how people learn OO. They learn that objects encapsulate behavior, and soon start deriving all kinds of non-objects to hold their actions ("ConnectionManager", "ConnectionHandler", etc.), while the state is kept all over the place. You should look at objects as just another data structure. Once you realize this, it's pretty clear that you should have a "Connection" that keeps the state and a bunch of methods to manipulate it. This comes natural if you program in C or other paradigms, where a "Connection" would be a struct or something like a hash. Another code-smell is a codebase littered with singletons.
- unclebucknasty 14y ago>* They learn that objects encapsulate behavior, and soon start deriving all kinds of non-objects to hold their actions* If I understand you correctly, it seems you would have reached the opposite conclusion: that is, if I learn that objects encapsulate behaviors/actions then I would create classes like "Connection" with all the attendant methods and would have no need for external classes like ConnectionManager. But, if I treat a Connection like a struct, then I would need these external classes like ConnectionManager to perform the actions. So, it seems exactly opposite from what you suggest.
- hcarvalhoalves 14y ago> So, it seems exactly opposite from what you suggest. Can I make it more clear? People learn (wrongfully) in OO that objects encapsulate behavior, so the first thing they do is create "Manager" classes and outline their program flow. This is even worse in languages that only gives you classes to work with - e.g., Java. Wrong. The first thing one should do is define the data structures - and when using OO, doubly so, because the data structures will map to classes seamlessly. When you have those "Manager/Controller/Handler" classes, it's a pretty big sign you're inventing a non-object to store all the control flow in one place, instead of thinking about proper objects and message passing.
- unclebucknasty 14y ago
- philwelch 14y agoThere should be similar guidelines for things like database tables. I've seen too many tables with names like "foo_data", "foo_info(s)", or even "foo_details" (in a one-to-many relationship from "foos").
- rachelbythebay 14y agoInstead of saying "don't do X", wouldn't it be easier to show a bunch of examples and let people map it onto their own problem space? Here, I'll start. These are some class names in my big depot here. They're not perfect, but what is? Dep: from my build tool, it's a dependency, like when you do #include "foo/bar.h", then foo/bar.o is the dep, and it is built from foo/bar.cc and foo/bar.h. It figures out the inputs and outputs and whether it needs to be rebuilt, and can do the building, too. DepTracker: it tracks all of the Deps. It's responsible for creating them as necessary and making sure they're all built (compiled) and ultimately linked if building a binary. HttpClient: uses libcurl, generates GETs and POSTs and the like, for tasks like fetching feeds (Atom/RSS), talking to Mozilla's Persona (browserid), and Stripe. HttpServer: uses libmicrohttpd, and gives the program an embedded HTTP server. This is great for debugging info. FormatPost: takes my flat text in and gives back formatted HTML for my "/w/" posts, Atom feed, or even the books. MySQLClient, PGSQLClient: interfaces to those external libraries as you would assume. ParseAtom, ParseRSS: turns different flavors of XML into something a little more reasonable for my own purposes. TCPSource, USRPSource, OsmoSDRSource: for different kinds of GNU Radio input scenarios. These are just a few of the larger set. The word "Manager" does not appear in any of them, but that wasn't a conscious decision. It just hasn't happened.
- shurcooL 14y agoBe that as it may, but it should also be easy to change the name later on (perhaps to amend your original mistake and refactor to a better structure and name). If your tools don't let you change class names easily, they have room for improvement.