views:

243

answers:

9

I am currently involved in a debate with my coworkers surrounding how I should design an API that will be used by my department. Specifically, I am tasked with writing an API that will serve as a wrapper facade to access Active Directory information - tailored to my company's/department's needs. I am aware that open source wrappers facades already exist but that is not the crux of this question and is merely being used to serve as an example.

When I presented my design proposal to my team, they shot me down because the API was not "configurable" enough. They claimed that they did not want the API to make the link between "Phone number" and <Obscure Active Directory representation of Phone number>. Every person in the meeting (except for me) agreed that they would prefer to ask around, "What is the correct field in Active Directory to use for the user's phone number?", and plug that into their respective apps (LOL!).

They asked me, "What if our company decides to use a different field for phone number and you weren't around to make the change in your source code?" They eventually admitted that they were afraid to be tasked with changing someone else's source code, even if the code was pristine and had extensive unit tests. Every senior IT person in my department was in agreement on this.

Is this really the correct attitude to have when designing software?!

+5  A: 

If I understood correctly, they want to have the option of mapping the links outside the code, be it through a configuration file, a database, whatever. If that is correct, I think they have a valid point - why be forced to change any code at all if all you need to do is to change a configuration mapping.

Otávio Décio
They would prefer for there to be no mapping at all. They want it so flexible that they would not have to maintain any sort of mapping. The problem with a configuration file or a database is that they would detract from the distributed nature of the API. Here's why: We have Active Directory nodes scattered throughout the globe. My API works off of the closest node. Unfortunately, we lack this sort of distributed nature in our databases and file servers, so pursuing this type of configuration would be less than ideal.
James Jones
If there's no mapping at all, then what's the point of even having an API? Just write something they can call to get a connection to the AD server. BTW, anyone who doesn't want to "change someone else's source code" has obviously never done any maintenance programming, so is obviously living in a fool's paradise...
TMN
+10  A: 

http://en.wikipedia.org/wiki/Inner_platform_effect

While hard-coding too many assumptions into your program is bad, overzealously avoiding hard-coded assumptions can be just as bad. If you try to make code excessively flexible, it becomes essentially impossible to configure, as the configuration scheme becomes almost a programming language in itself. I think in general, phone number is a common enough thing that it can just be hard coded as a field.

dsimcha
Wow, the link and your description completely jives with what I'm trying to convey to my team. Thank you!
James Jones
+1  A: 

If you're saying "should I hard code everything", then I think it's not a good idea.

In 2 years you will be gone and there will be a programmer that will waste a lot of time trying to update your legacy code when updating a configuration file would have been way easier.

In some cases it makes sense to hard code information, but I' don't think that your situation is one of these cases. I'd need more knowledge of the situation to be sure, this is just my guess from what you said.

marcgg
Hardcore! Woo!!!
James Jones
aha, it's fixed
marcgg
+1  A: 

It seems easy enough to do both: produce a flexible API which allows the field to be specified, and then a wrapper around it which knows about the obscure ActiveDirectory name.

Of course, you could build that flexible solution later and just hard code the name for the moment. If that's significantly easier than the two-pronged approach, it's reasonable to argue for it - but if you'd probably end up with that sort of separation internally anyway, then it doesn't do much harm to expose it.

Jon Skeet
+2  A: 

Like an individual, a company has finite time to maintain existing projects. It is not unreasonable to request that the software can be configured to produce different results based on given criteria.

For example it is common to use a data store (i.e., configuration files or a database) to control system behaviour. The underlying code needs to be flexible enough to adapt to the various control inputs.

The amount of work between hardcoding constants and moving those constants into a resource bundle (in Java) is negligable.

Dave Jarvis
+1  A: 

I can honestly say I have been in your position before and I agree with the argument they are presenting you. Especially with an in-house app you will see feature creep. The more useful your application, the worse the feature creep. It is possible your application could be used in another office and they will have fields mapped differently than your current office. If you hard code mappings you are then stuck with different versions for different locations. Maintaining separate versions of source code quickly becomes a nightmare for a programmer. If you design in configurability now and your application is forgotten you have lost very little, but if your application becomes a standard across the company you have saved yourself an immense amount of time in the future.

Beaner
+3  A: 

If possible, you should always err on the side of more configurable. It will save you headaches later.

Column Names

Specifically in your case, columns in tables are an inherently non-static variable. They will commonly change as your needs change.

If you have a "phonenum" column, then they add a second phone number, they change the column to "phonenum1" and "phonenum2". It would need to be changed in the code. Then if they change them to "Home_Phone", "Work_Phone", "Cell_Phone" then the code would again have to be changed. If, however, you had a mapping file (a key/value config file) then all these changes would be extremely simple to make.

In General

I disagree with dsimcha that an application can be 'too configurable'. What he is talking about is 'feature bloat', where there are so many intertwining configurables that it becomes impossible to change any one without futzing all the others. This is a very real problem. However, the problem is not the number of configuring options, the problem is how they are presented to the user.

If you present all the configuration options in a concise, clear, streamlined manner. There should be comments to explain each one, and how it interacts with the others. In that case, you can have as many configuration variables as you want, because you have been careful to keep them segregated into singles or pairs, and have marked them as such.

You should be writing applications so that external (environmental) changes do NOT require code changes. Things such as

  • Database user password changes
  • Column names change
  • "Temp folder" location changes
  • Target Machine name/ip change
  • App needs to be run twice a day instead of once
  • Logging levels

None of those changes affect the function of the application and so there should be NO CODE CHANGES required. That is the metric you should use if you ever wonder whether hard-coding is all right.

If the fuctionality needs to change, it should be a code change. Otherwise, make it configurable.

I think you misunderstood dsimcha. Here is my interpretation of his answer: as my facade class becomes increasingly flexible, it becomes just as complex as the classes I'm trying to simplify, thereby increasing the overall complexity of the system.
James Jones
@James Jones: No, I understood what he was saying. But it represents a misunderstanding 'configurability' vs 'modularity'. Configurability should mean that you have the option of changing VALUES in your code, not the functionality. If your 'configuration' options actually change the code (as dsimcha indicated) then you are putting modularity into your config, which is bad. Modules should be handled separately. In your case, because the column name is a value that could change, it should **100%** be in a config file.
I think there is some confusion with how the term "configurable" is being used. My team was suggesting that I make make the API more "configurable" in the sense that there would be no mapping to columns whatsoever - that they would reference the columns directly. I think I made this pretty clear in my question.
James Jones
So, not even a config file?
Right. They would like to keep control over what columns are used by referencing them directly. Part of the reason is because our Active Directory nodes are literally scattered all over the globe and we do not have a distributed file system to host the config file on. I agreed with them on this point. However, they also said that *even if* we had a DFS, a config file would not be desirable because it would require them having to locate it and edit it. THIS is what blew my mind.
James Jones
It sounds to me like their arguments are strong. It would make the application MORE usable. The fact that if there WAS a config file, they STILL wouldn't edit it. That's fairly mindblowing, but in that case, I'd just write a stupidly-simple winforms app for "editing the config values" You could probably write than in under an hour.
+1  A: 

Fear of change, as well as fear of accountability for making a change, is not uncommon in IT software organizations. Often, the culture in the organization is what drives this attitude.

Having said that, in your specific example, you are describing an API that provides a facade on top of the ActiveDirectory service - one that appears to be intended to be used by different groups and/or projects in your organization.

In that particular scenario, it makes sense to make portions of your API support configurability, since you may ultimately find that the requirements for different projects or groups could be different, or change over time.

As a general practice, when I build code that involves a mapping of one programming interface to another and there are data mapping considerations involved, I try to make the mapping configurable. I've found that this helps both unit testing as well as dealing with evolving requirements or contradictory requirements from different consumers.

LBushkin
Thank you for picking out that I am using the facade pattern. I edited the post to make it more clear.
James Jones
A: 

I think it depends on why the API is being created, and what problems you're aiming to solve. If the aim of the API is to be a service that lives on a server somewhere and manages requests from different applications, then I think your approach is probably the way to go, with the addition of a database or config files to perhaps customize the LDAP paths of certain properties.

However, if the goal of the API is to simple be a set of classes that abstract away the details of accessing Active Directory, but not what properties are being accessed, then what your coworkers have specified is the way to go.

Either approach isn't necessarily right or wrong, so it ultimately depends on your overall reasons for creating the API in the first place.

tbreffni