There are different types of interfaces, for most non technical folks when the term interface is used we thing of a graphic user interface or GUI. The type of interface you click around in with a mouse. For the more abstractly minded everything is an interface, the steering wheel in your care is an interface, coupled with the other controls they allow you to drive your care. Otherwise your car is just a pile of metal, rubber and plastic with no purpose, except maybe as art. What I want to talk about are application programming interfaces or APIs, the kind of interface that I create and use all day long as a server side developer.
What makes a good API is ease of use, the package, module or library has to do something that needs to be done, but after that the collection of types and functions that comprise the API are important in how useful a piece of software is. Unfortunately ease of use is something most developers are not paying attention to while trying to solve a problem. We've all used the kinds of interfaces that require you to stand on your head and type with one are behind your back, and then after compiling the source the software only works on every third Wednesday of an odd month that is divisible by 3... Sometimes obscure interfaces are on purpose, as in the case with some shareware that I had the displeasure to encounter in the mid 2000's. The API was good enough to get you started, but once you committed to the technology and started to make full use of the API things went wrong. Suddenly things became harder and harder until an expensive consult from the individual or foundation who created the software was required to salvage your efforts. That experience still gets me mad every time I think about it.
A good interface is also going to be subjective, the personal style and biases of those who use the interface, and the language or languages that can use the interface all play into how "good" an interface is. There are, I would consider, objective signs in the quality of an interface and I'll describe some of them here.
Argument Interaction
As a Python developer this is something I see often by developers who are new to Python and have come from languages such as Java where method overloading is common. The new Python developer feels the need to have the fewest members to their interface as possible and without the ability to overload the same member name invent ever more complex conditional logic on a growing number of arguments to the method to cram as much functionality into the member as possible. As an example
def my_cool_member(arg1,arg2,kwarg1=None,kwarg2=None,**kwargs):
if kwarg1:
arg1 = kwarg1 + arg2 + arg1
else:
arg1 = arg2 + arg1
if kwarg2 and kwarg1:
...
and so on. In general don't drive conditional logic off of the presence of optional keyword arguments, the caveat is if the keyword argument is indented as a modifier.
def my_cool_member(arg1,arg2,is_this=False,is_that=False):
if is_this:
//do something for this case
if is_that:
//do something for that case
if is_this and is_that:
//do something for the combined case
...
A few other rules to go by are, do not make required arguments keyword arguments. If a value, needed to execute a function in a stable state, is required then make the submission of the value on the argument required. A stark example is this
def my_function(required=None):
required.attribute
...
Don't do that, I'll find you and make you wear a dunce cap for a week. Another rule is for keyword arguments to have default values that allow success execution of the function. Don't do this
def my_function(arg,kwarg=None):
result = arg.method(kwarg) //requires a non None value
...
Again there will be a dunce cap in your future.
The trick is, is that code like this has a way of creeping into everyones work. There is a deadline and you are in a hurry, you are also doing all the server and DB setup (devops a case of white-washing-the-fence if I've ever seen one) and you don't have time to refactor for a new signature (hey it happens, you will violate the contract an API represents.) What separate the engineers from the developer in his mom's basement is tracking that piece of technical debt and paying it off as soon as possible.
The other aspect of a good API is documentation. In Python that is why we have PEP8, read it, know it, use it and there is no need to repeat it here. In general a one or two sentence description of use is more than enough. If you find that your docstring is 50 lines long then you have a hard to use complex member to your interface and you need to refactor.
No comments:
Post a Comment