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 5 years ago.
Improve this question
For simple getters/setters, like the one below, what's the best way to document it?
public float getPrice()
{
return price;
}
I'm pretty strict about coding standards, so my IDE warns me about any undocumented public/protected methods.
Option 1:
/**
* Get the price field.
*
* #return
*/
Option 2:
/**
* #return Price
*/
Or don't document it at all?
If "price" is anything other than the most obvious value, then your comment should describe what "Price" means and is used for, not just what it is called.
Some hypothetical examples:
Is it the "price before tax" or the "price including tax"?
Is it expressed in dollars, euros or pounds?
Is it rounded to the nearest cent, 5 cents, or dollars?
Is a special value returned to indicate a free item (e.g. 0.0f)?
Can a price be "uninitialised", and if so, what value is returned (e.g. -1.0f)?
For a good proportion of methods and properties, there is something you can say that tells the reader more than just the name will tell them. That will save other progammers a lot of time and reduce the risk of bugs. Even if it merely confirms their guesses/assumptions, it will still save them time.
In the case of "simple" values that are totally self-explanatory (e.g. Rectangle.Width), then don't waste your time typing - AtomineerUtils will create that level of documentation for you with a single keypress. (The advantage of AtomineerUtils in your case is that it supports Doxygen, Javadoc and Documentation XML comment formats, and VB, C#, C++/CLI, C++ and C code, so you can retain your existing format while massively reducing the time you spend on documentation commenting. GhostDoc will do a similar job, but it only supports Xml documentation for VB and C#)
I'd write the bare minimum to keep the linter quiet. If it's obvious what the getter/setter is getting/setting, I'd use some copy-paste documentation that makes it clear that nothing fancy is going on:
/**
* Simple getter.
* #return Price
*/
I personally consider too many getters and setters to be a code smell, as it's a possible sign that you're not providing operations at the correct level of abstraction (this is obviously not always true, but a rule of thumb).
Describe the minimum for another programmer to understand what the method does or returns.
I would use this:
/**
* #return the price.
*/
or
/**
* Returns the prize.
*
* #return the price.
*/
This duplicates the same text, but a it might be necessary if you agreed on certain coding standards that require a description and not only the tags.
I would not mention that it returns the price field, since that describes the internal representation.
Document the interface as if the user knew nothing about the implementation. The docs are for callers of the method, who don't have to know or care what the specific internal state is, but do have to care what the method does for them.
I was looking for a standard way to doco functions until i searched SO and found people using:
GhostDoc - http://submain.com/products/ghostdoc.aspx
It's one of the best auto doco tools out there and formats each of your comments the same way. The best thing about it is if your methods are aptly named, then you don't even need to edit the auto-generated doco as it will make sense.
Also, the comments comes up when you use intellisense so you can be reminded of what your code does a month after you've written it! :)
GhostDocs will do this to your property: (shortcut Ctrl+Shift+D)
/// <summary>
/// Gets the price.
/// </summary>
/// <returns></returns>
public float getPrice()
{
return price;
}
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a corporate application written in python/Django (no python experience required to answer this). Its SAAS basically.
Few of the clients seems to have different requirement for a few modules.
Lets say there is a URL
www.xyz.com/groups
which is used by all clients but a few of the clients want to have different output on call of the same URL.
I want to know how can i do that without writing new function for each client or writing conditions in a single function.
Its a silly question i know but there must be some solution to it, i know.
If your code is required to do "A" for case "a" and "B" for case "b" and "C" for case "c", then regardless of what solution you pick, somewhere in the code has to exists something that decides whever or not case 'a/b/c' occurs, and something must exist that will dispatch correct 'A/B/C' action for that case, and of course those A/B/C actions have to be written somewhere in the code, too.
Step outside of the code and think about it. If it is specified and must happen - it has to be coded somewhere. You cannot escape that. Now, if the cases/actions are trivial and typical, you might find some more-or-even-more configurable library that accidentally allows you to configure such cases and actions, and off you go, you have it "with no code" and no "clutter". But looking formally, the code is deep there in the library. So, the decider, dispatcher and actions are coded. Just not by you - by someone that guessed your needs.
But if your needs are nontrivial and highly specific, for example, if it require your various conditions to decide which a/b/c case is it - then most probably you will have to code the 'decider' part for yourself. That means lots of tree-of-IFs, nested-switches, rules-n-loops, or whatever you like or feel adequate. After this, you are left with dispatch/execute phase, and this can be realized in a multitude of ways - i.e. strategy pattern - it is exactly it: dispatch (by concrete class related to case) and execute (the concrete strategy has the concrete code for the case).
Let's try something-like-OO approach:
For example, if you have cases a/b/c for UserTypes U1,U2,U3, you could introduce three classes:
UserType1 inherits from abstract UserType or implements "DoAThing" interface
UserType2 inherits from abstract UserType or implements "DoAThing" interface
UserType3 inherits from abstract UserType or implements "DoAThing" interface
UserType1 implements virtual method 'doTheThing' that executes actionA
UserType2 implements virtual method 'doTheThing' that executes actionB
UserType3 implements virtual method 'doTheThing' that executes actionC
your Users stop keeping "UserType" of type "int" equal to '1/2/3' - now their type is an object: UserType1, UserType2 or UserType3
whenever you must do the thing for a given user, you now just:
result = user.getType().doTheThing( ..params..)
So, instead of iffing/switching, you use OO: tell, don't ask rule. If the action-to-do is dependent solely on UserType, then let the UserType perform it. The resulting code is as short as possible - but at the cost of number of classes to create and, well, ...
... the decider, dispatcher and actions are still in the code. Actions - obvious - in the various usertype clasess. Dispatch - obvious - virtual call by common abstract base method. And decider..? Well: someone at some point had to choose and construct the correct UserType object for the user. If user was stored in the database, if "usertype" is just an integer 1/2/3, then somewhere in your ORM layer those 1/2/3 numbers had to be decoded and translated into UserType1/2/3 classes/objects. That means, that you'd need there a tree-of-ifs or a switch or etc. Or, if you have an ORM smart enough - you just set up a bunch of rules and it did it for you, but that's just again delegating part of the job to more-or-even-more configurable library. Not mentioning that your UserType1/2/3 classes in fact became somewhat .. strategies.
Ok, let's attack the 'choose' part.
You can build a tree of ifs or switches somewhere to decide and assign, but imperative seems to smell. Or, with OO, you can try to polymorphize something so that "it will just do the right thing", but it will not solve anything since again you will have to choose the object type somewhere. So, let's try data-driven: let's use lookups.
we've got five implementations of an action
create a hash/dictionary/map
add usertype1->caseA to the map
add usertype2->caseC to the map
add usertype3->caseB to the map
add usertype4->caseA to the map
add usertype5->caseE to the map
....
now, whenever you have a user and need to decide, just look it up. Instead of a "case" you may hold a ready to use object of a strategy. Or a callable method. Or a typename. Or whatever you need. The point is that instead of writing
if( user.type == 1) { ... }
else if( user.type == 2) ...
or switching, you just look it up:
thing = map[ user.type ]
if ( thing is null ) ???
but, mind that without some care, you might sometimes NOT find a match in the map. And also, the map must be PREDEFINED for ALL CASES. So, simple if X < 100 may turn up into a hundred of entries 0..99 inside the map.
Of course, instead of a map, you may use some rule-engine and you could define a mapping like
X<100 -> caseA
X>=100 -> caseB
and then 'run' the rules against your usertype and obtain a 'result' that will tell you "caseA".
And so on.
Each of the parts - decide, dispatch, execute - you may implement in various ways, shorter or longer, more or less extensible, more or less configurable, as OO/imperative/datadriven/functional/etc - but you cannot escape them:
you have to define the discriminant of the cases
you have to define the implementation of the actions
you have to define the mapping case-to-action
How to do them, is a matter of your aesthetics, language features, frameworks, libraries and .. time you want to spend on creating and mantaining it.
I'll take a real example I have to implement in a program I'm coding:
I have a database that has the score of every game bowled in the past three years in a bowling center. With a GUI, you can choose to either search for the best score on each lane, search for the best score between two dates, for the best score for each week, etc.
I'm wondering what the best way to implement this is. Should I code something like this:
public Vector<Scores> grabMaxScores(sortType, param1, param2)
{
if(sortType.equals("By lane"))
...
else if(sortType.equals("Between given dates")
...
}
Or is it more appropriate to code different methods for each type and call the correct one in the listener?
public Vector<Scores> grabMaxScoresBetweenDates(startDate, endDate)
{
...
}
public Vector<Scores> grabMaxScoresByLane(minLane, maxLane)
{
...
}
I'm not necessarily asking for this particular problem, it's just a question I find asking myself often when I'm coding multiple methods that are alike where the principle is the same, but the parameters are different.
I can see there are good reasons to use each of them, but I want to know if there is a "more correct" or standard way of coding this.
In my personal opinion, I would prefer your second option over the first. This is because you have the opportunity to be precise about things like the types of the parameters. For example, minLane and maxLane may just be integers, but startDate and endDate could very well be Date objects. It's often nicer if you can actually specify what you expect, as it reduces the need for such things as casting and range checks, etc. Also, I would find it more readable, as the function names just say what you are trying to do.
However, I may have an alternative idea, which is kind of a variation on your first example (I actually got this inspiration from Java's Comparator, in case you're familiar with that). Rather than pass a string as the first argument, pass some sort of Selector object. Selector would be the name of a class or a interface, which would look something like so (in Java):
interface Selector {
public void select(Score next);
public Score getBest( );
}
If the select method "likes" the value of next which is given to it, it can store the value for later. If it doesn't like it, it can simply discard it, and keep whatever value it already has. After all the data is processed, the best value will be left over, and can be requested by calling getBest. Of course, you can alter the interface to suit your particular needs (e.g. it seems like you might be expecting more than one value to be retrieved. Also, generics might help a lot as well).
The reason I like this idea is that now your function is very general purpose. In order to add new functionality, you don't need to add functions, and you don't need to modify any functions you already have. Instead, the user of your code can simply define their own implementation of Selector as they see fit. This allows your code to be far more compositional, which makes it easier to use. The only inconvenience is the need to define implementations of Selector, though, you could also provide several default ones.
The approach you have used would also work. But if you want to add some new functionality like "get lowest scores on Friday evening", you will need to add one more function, which kinda not so good thing to do.
As you have already have the data in a database you can generate database queries which would fetch the required results and display. So you need not modify your code every time.
I'm writing some javadocs (actually they are jsdocs but it doesn't make a difference for this question) and found this repeating pattern:
Imagine a method that just returns a value, maybe product of some calculation. For example, let say it is the time in milliseconds since the unix epoch.
public long getTimeSinceTheEpoch(){
//calculate time
return time;
}
So far, so good. Now when the time comes to add javadocs (or jsdocs, or rdocs, whatever), I've been writing something like this:
/**
* Gets the time in milliseconds since the unix epoch
*
* #returns the time in milliseconds since the unix epoch
*/
public long getTimeSinceTheEpoch(){
Here, the problem is obvious.
My question is, what do you put in the body of the comment, and what do you choose for the #returns attribute of the comment?
IMPORTANT
I'm not a fan of these kind of comments, if it depended on me I would rename the method to something like getTimeInMillisecondsSinceTheEpoch and avoid the comments at all.
I cannot do that (avoid the comments), so I'm striving to make them as useful as possible.
Best is to provide only the #return description as you need to document what you are returning for sure.
In the comment section, you could also throw in that same one-liner but also add how you are going to go about returning what you return, for e.g.
/**
* Gets the time in milliseconds since the unix epoch
* by doing something incredible.
* http://stackoverflow.com/questions/4307142/documenting-a-method-that-just-returns-something
*
* #note thank you stackoverflow
*
* #returns the time in milliseconds since the unix epoch
*/
public long getTimeSinceTheEpoch(){
The Sun (now Oracle) style guide "How to Write Doc Comments for the Javadoc Tool" recommends this:
The #return tag is required for every
method that returns something other
than void, even if it is redundant
with the method description. (Whenever
possible, find something non-redundant
(ideally, more specific) to use for
the tag comment.)
I'm not fond of the redundancy, and it goes against the DRY principle. Personally, I either make one a summary and the other a detail (as suggested above), or provide only an #return. As you point out, the name of a simple getter may suffice as the summary.
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
I have some code like this in my application. It writes out some XML:-
public void doStuff( Business b, XMLElement x)
{
Foo f = b.getFoo();
// Code doing stuff with f
// b is not mentioned again.
}
As I understand it, the Law of Dementer would say this is bad. "Code Complete" says this is increasing coupling. This method should take "f" in the first place.
public void doStuff( Foo f, XMLElement x)
{
// Code doing stuff with f
}
However, now I have come to change this code, and I do actually need to access a different method on b.
public void doStuff( Business b, XMLElement x)
{
Foo f = b.getFoo();
// Code doing stuff with f
// A different method is called on b.
}
This interface has made life easier as the change is entirely inside the method. I do not have to worry about the many places it is called from around the application.
This suggests to me that the original design was correct. Do you agree? What am I missing?
PS. I do not think the behaviour belongs in b itself, as domain objects do not know about the external representation as XML in this system.
First thing is that this isn't necessarily a Law of Demeter violation, unless you are actually calling methods on the Foo object f in doStuff. If you are not, then you are probably fine; you're only using the interface of the Business object b. So I'll assume that you are calling at least one method on 'f'.
One thing you might be "missing" is testability, specifically unit tests. If you have:
public void doStuff( Business b, XMLElement x)
{
Foo f = b.getFoo();
// stuff using f.someMethod
// business stuff with b
// presumably something with x
}
... then if you want to test that doStuff does the right thing for different Foo, you have to first create (or mock) a new Business object with each Foo 'f' that you want, then plug that object into doStuff (even if the rest of the Business-specific stuff is identical). You're testing at one remove from your method, and while your source code may stay simple, your test code gets messier. So, if you really need both f and b in doStuff, then arguably they should both be parameters.
For more reading on it, this person is one of the most emphatic Law of Demeter campaigners I've come across; frequently provides rationales for it.
I think it's difficult to give you a clear-cut answer because
1) the problem statement is pretty abstract, and
2) there is no "absolute" good design - it depends on what's around your classes too, and what was a good design initially might evolve into something you want to refactor as your system grows and evolves, and your understanding of the domain becomes more refined.
I don't see the first example as a "massive" violation of the Demeter principle, but again everything is in the details, it depends on how much is going on in your commented section - you can always add more indirection if you need to. You could for instance have your method "DoStuff" on a WriteBusinessObjectToXmlService class, and if the amount of work you were doing involving f was growing, you could extract it into its method "DoStuffWithF(f, x)", or even create a separate class WriteFToXmlService, with DoStuff(f, x).
If we follow with this logic further we will come up with an idea that a global-everything-objects-repository object (or service locator) should be used which contains links to everything in the system. Than we will not need to change method signatures at all because this repository is all we need.
The problem is that the purpose of the method has changed, but the signature has not. If Foo is everything the method needs than it should accept Foo only. This way we can tell that it operates solely on Foo. This will communicate the purpose of the method more clearly. If it suddenly needs Business too we need to change the method signature because it should indicate other method purpose and requirements
Maybe it is now justified to pass in Business or the method needs a third parameter: the return type of the other method called on the Business object. It depends on the rest of the body of the doStuff method.
Do you often see in API documentation (as in 'javadoc of public functions' for example) the description of "value limits" as well as the classic documentation ?
Note: I am not talking about comments within the code
By "value limits", I mean:
does a parameter can support a null value (or an empty String, or...) ?
does a 'return value' can be null or is guaranteed to never be null (or can be "empty", or...) ?
Sample:
What I often see (without having access to source code) is:
/**
* Get all readers name for this current Report. <br />
* <b>Warning</b>The Report must have been published first.
* #param aReaderNameRegexp filter in order to return only reader matching the regexp
* #return array of reader names
*/
String[] getReaderNames(final String aReaderNameRegexp);
What I like to see would be:
/**
* Get all readers name for this current Report. <br />
* <b>Warning</b>The Report must have been published first.
* #param aReaderNameRegexp filter in order to return only reader matching the regexp
* (can be null or empty)
* #return array of reader names
* (null if Report has not yet been published,
* empty array if no reader match criteria,
* reader names array matching regexp, or all readers if regexp is null or empty)
*/
String[] getReaderNames(final String aReaderNameRegexp);
My point is:
When I use a library with a getReaderNames() function in it, I often do not even need to read the API documentation to guess what it does. But I need to be sure how to use it.
My only concern when I want to use this function is: what should I expect in term of parameters and return values ? That is all I need to know to safely setup my parameters and safely test the return value, yet I almost never see that kind of information in API documentation...
Edit:
This can influence the usage or not for checked or unchecked exceptions.
What do you think ? value limits and API, do they belong together or not ?
I think they can belong together but don't necessarily have to belong together. In your scenario, it seems like it makes sense that the limits are documented in such a way that they appear in the generated API documentation and intellisense (if the language/IDE support it).
I think it does depend on the language as well. For example, Ada has a native data type that is a "restricted integer", where you define an integer variable and explicitly indicate that it will only (and always) be within a certain numeric range. In that case, the datatype itself indicates the restriction. It should still be visible and discoverable through the API documentation and intellisense, but wouldn't be something that a developer has to specify in the comments.
However, languages like Java and C# don't have this type of restricted integer, so the developer would have to specify it in the comments if it were information that should become part of the public documentation.
I think those kinds of boundary conditions most definitely belong in the API. However, I would (and often do) go a step further and indicate WHAT those null values mean. Either I indicate it will throw an exception, or I explain what the expected results are when the boundary value is passed in.
It's hard to remember to always do this, but it's a good thing for users of your class. It's also difficult to maintain it if the contract the method presents changes (like null values are changed to no be allowed)... you have to be diligent also to update the docs when you change the semantics of the method.
Question 1
Do you often see in API documentation (as in 'javadoc of public functions' for example) the description of "value limits" as well as the classic documentation?
Almost never.
Question 2
My only concern when I want to use this function is: what should I expect in term of parameters and return values ? That is all I need to know to safely setup my parameters and safely test the return value, yet I almost never see that kind of information in API documentation...
If I used a function not properly I would expect a RuntimeException thrown by the method or a RuntimeException in another (sometimes very far) part of the program.
Comments like #param aReaderNameRegexp filter in order to ... (can be null or empty) seems to me a way to implement Design by Contract in a human-being language inside Javadoc.
Using Javadoc to enforce Design by Contract was used by iContract, now resurrected into JcontractS, that let you specify invariants, preconditions, postconditions, in more formalized way compared to the human-being language.
Question 3
This can influence the usage or not for checked or unchecked exceptions.
What do you think ? value limits and API, do they belong together or not ?
Java language doesn't have a Design by Contract feature, so you might be tempted to use Execption but I agree with you about the fact that you have to be aware about When to choose checked and unchecked exceptions. Probably you might use unchecked IllegalArgumentException, IllegalStateException, or you might use unit testing, but the major problem is how to communicate to other programmers that such code is about Design By Contract and should be considered as a contract before changing it too lightly.
I think they do, and have always placed comments in the header files (c++) arcordingly.
In addition to valid input/output/return comments, I also note which exceptions are likly to be thrown by the function (since I often want to use the return value for...well returning a value, I prefer exceptions over error codes)
//File:
// Should be a path to the teexture file to load, if it is not a full path (eg "c:\example.png") it will attempt to find the file usign the paths provided by the DataSearchPath list
//Return: The pointer to a Texture instance is returned, in the event of an error, an exception is thrown. When you are finished with the texture you chould call the Free() method.
//Exceptions:
//except::FileNotFound
//except::InvalidFile
//except::InvalidParams
//except::CreationFailed
Texture *GetTexture(const std::string &File);
#Fire Lancer: Right! I forgot about exception, but I would like to see them mentioned, especially the unchecked 'runtime' exception that this public method could throw
#Mike Stone:
you have to be diligent also to update the docs when you change the semantics of the method.
Mmmm I sure hope that the public API documentation is at the very least updated whenever a change -- that affects the contract of the function -- takes place. If not, those API documentations could be drop altogether.
To add food to yours thoughts (and go with #Scott Dorman), I just stumble upon the future of java7 annotations
What does that means ? That certain 'boundary conditions', rather than being in the documentation, should be better off in the API itself, and automatically used, at compilation time, with appropriate 'assert' generated code.
That way, if a '#CheckForNull' is in the API, the writer of the function might get away with not even documenting it! And if the semantic change, its API will reflect that change (like 'no more #CheckForNull' for instance)
That kind of approach suggests that documentation, for 'boundary conditions', is an extra bonus rather than a mandatory practice.
However, that does not cover the special values of the return object of a function. For that, a complete documentation is still needed.