Related
I work on a class in VBA, that encapsulates downloading stuff with MSXML2.XmlHttp.
There are three possibilities for the return value: Text, XML and Stream.
Should I create a function for each:
aText=myDownloader.TextSynchronous(URL,formData,dlPost,....)
aXml.load myDownloader.XmlSynchronous(URL,formData,dlPost,....)
Or can I just return the XmlHttpObject I created inside the class and then have
aText=myDownloader.Synchronous(URL,formData,dlPost,.....).ResponseText
aXML=myDownloader.Synchronous(URL,formData,dlPost,.....).ResponseXML
In the former case I can set the obj to nothing in the class but have to write several functions that are more or less the same.
In the latter case, I relay on the "garbage collector" but have a leaner class.
Both should work, but which one is better coding style?
In my opinion, the first way is better because you don't expose low level details to a high level of the abstraction.
I did something similar with a web crawler in Java, so I have a class only to manipulate the URL connection getting all the needed data (low level) and a high level class using the low level class that return an object called Page.
You can have a third method that only execute myDownloader.Synchronous(URL,formData,dlPost,.....) and stores the returned object in a private variable and the others method only manipulate this object. This form, you will only open the connection one time.
After much seeking around in the web (triggered by the comment by EmmadKareem) I found this:
First of all, Dont do localObject=Nothing at the end of a method - the variable goes out of scope anyway and is discarded. see this older but enlightening post on msdn
VBA uses reference counting and apart from some older bugs on ADO this seems to work woute well and (as I understand) immediately discards ressources that are not used anymore. So from a performance/memory usage point of view this seems not to be a problem.
As to the coding style: I think the uncomfortable fdeeling I had when I designed this could go away by simply renaming the function to myDownloader.getSyncDLObj(...) or some such.
There seem to be two camps on codestyle. One promotes clean code, which is easy to read, but uses five lines everytime you use it. Its most important prerogative is "every function should do one thing and one thing only. Their approach would probably look something like
myDownloader.URL="..."
myDownloader.method=dlSync
myDownloader.download
aText=myDownloader.getXmlHttpObj.ResponseText
myDownloader.freeResources
and one is OK with the more cluttered, but less lineconsuming
aText=myDownloader.getSyncObj(...).ResponseText
both have their merits both none is wrong, dangerous or frowned upon. As this is a helper class and I use it to remove the inner workings of the xmlhttp from the main code I am more comfortable with the second approach here. (One line for one goal ;)
I would be very interested on anyones take on that matter
Context: I need to explain "composed methods" to a group of mixed-experience.
I think I heard about it first while reading Beck's Smalltalk Best practices. I've personally not had too many issues writing such methods - however in the local code-wilderness, I've seen quite a few instances where the lack of composed methods had created indecipherable Blobs... and I was in the minority. So I'm taking them through CleanCode - where this one popped up again.
The premise is quite simple.
"Functions should be short, do one
thing well and have an
intention-revealing name. Each step in
the body of the method should be at
the same level of abstraction."
What I'm struggling with a check for the "same level of abstraction".. viz.. forgive the pun a bit abstract for beginners.
My current explanation would be similar to SICP's "wishful thinking". (Imagine the ideal set of steps and then worry about implementation/making it happen.").
Does anyone have a better set of rules / an acid test to evaluate your decisions while writing composed methods ?
Same level of abstraction - examples:
void DailyChores()
{
Dust();
Hoover();
MopKitchenFloor();
AddDirtyClothesToWashingMachine();
PlaceDetergentInWashingMachine();
CloseWashingMachineDoor();
StartWashingMachine();
Relax();
}
Hopefully it should be clear that the WashingMachine saga would be better extracted into a separate method entited WashDirtyLaundry();
Arguably the MopKitchenFloor should also be in a separate method entitled CleanKitchen() as quite likely you would want to extend this in the future to include WashPots(), DefrostFridge() etc.
So a better way would be to write as follows:
void DailyChores()
{
Dust();
Hoover();
CleanKitchen(CleaningLevel.Daily);
WashDirtyClothes();
Relax();
}
void WashDirtyClothes()
{
AddDirtyClothesToWashingMachine();
PlaceDetergentInWashingMachine();
CloseWashingMachineDoor();
StartWashingMachine();
}
void CleanKitchen(CleaningLevel level)
{
MopKitchenFloor();
WashPots();
if(level == CleaningLevel.Monthly)
{
DefrostFridge();
}
}
enum CleaningLevel
{
Daily,
Weekly,
Monthly
}
In terms of "rules" to apply to code not following this principle:
1) Can you describe what the method does in a single sentence without any conjunctions (e.g. "and")? If not split it until you can. e.g. In the example I have AddDirtyClothesToWashingMachine() and PlaceDetergentInWashingMachine() as separate methods - this is correct - to have the code for these 2 separate tasks inside one method would be wrong - however see rule 2.
2) Can you group calls to similar methods together into a higher level method which can be described in a single sentence. In the example, all of the methods relating to washing clothes are grouped into the single method WashDirtyClothes(). Or in consideration of rule 1, the methods AddDirtyClothesToWashingMachine() and PlaceDetergentInWashingMachine() could be called from a single method AddStuffToWashingMachine():
void AddStuffToWashingMachine()
{
AddDirthClothesToWashingMachine();
PlaceDetergentInWashingMachine();
}
3) Do you have any loops with more than a simple statement inside the loop? Any looping behaviour should be a separate method. Ditto for switch statements, or if, then else statements.
Hope this helps
I take "acid test" to mean you would like some concrete rules that help embody the abstract concept in question. As in "You might have mixed levels of abstraction if..."
You might have mixed levels of abstraction if...
you have a variable in the function that is only used for part of the function.
you have multiple loops in the function.
you have multiple if statements who's conditions are independent of each other.
I hope others will add to the above...
EDIT: Warning - long answer from self-taught guy ahead . . .
In my very humble opinion (I am TOTALLY learning here as well) it seems BonyT and Daniel T. are on the right track. The piece which might be missing here is the design part. While it is safe to say that refactoring/composing will always be a necessity, might it also be as safe to say that (ESPECIALLY with beginners!) proper design up front would be the first, second, and third steps to properly composed code?
While I get what you are asking (a test/set of tests for code composition), I think BonyT is applying the earliest of those tests during the "pseudocode" part of the design process, no?
Obviously, in the early stages of project planning, strong design and experienced coders will sniff out the obvious places ripe for composition. As the work progresses, and the team is beginning to fill these initial code stubs with body, some slightly more obtuse exaples are bound to crop up. BonyT's example presents these first two steps quite well.
I think there comes a point at which experience and a finely-tuned "nose" for code smell comes in - in other words, the part you may not be able to teach directly. However, that is where Daniel T's answer comes in - while one may not be able to develop concrete ACID-type "tests" for proper composition, one CAN employ techniques such as Daniel proposes to seek out potential smelly code. Detect "hints" if you will, that should at least prompt further investigation.
If one is not certain whether things are composed at the proper level, it might make sense to work through a particular function and attempt to describe, step-by-step, what is going on in simple, single sentences without conjuctions. This is probably the most basic ACID-type test that could be performed. Not to mention, this process would by default end up correctly documenting the code . . .
In response to BonyT you imply that his pseudocode/method stubs make the next step obvious - I am betting that if one walks through a function and describes things step by step, one will often find that indeed, the next step either obviously follows at the same level of detail, or belongs elsewhere. While there will obviously be cases (many, with complex code) where things are not so neat, I propose that this is where nothing but experience (and possibly genetics!) come in - again, things you can't teach directly. At that point, one must examine the problem domain, and determine a solution which best fits the domain (and also be prepared to change it down the road . . .). Once again, properly documenting the "in-between" cases with short, simple statements (and narrative describing decisions in gray areas) will help the poor maintenence guy down the road.
I realize that I have proposed nothing new here, but what I had to say was longer than a comment would allow!
I often find myself needing reference to an object that is several objects away, or so it seems. The options I see are passing a reference through a middle-man or just making something available statically. I understand the danger of global scope, but passing a reference through an object that does nothing with it feels ridiculous. I'm okay with a little bit passing around, I suppose. I suspect there's a line to be drawn somewhere.
Does anyone have insight on where to draw this line?
Or a good way to deal with the problem of distributing references amongst dependent objects?
Use the Law of Demeter (with moderation and good taste, not dogmatically). If you're coding a.b.c.d.e, something IS wrong -- you've nailed forevermore the implementation of a to have a b which has a c which... EEP!-) One or at the most two dots is the maximum you should be using. But the alternative is NOT to plump things into globals (and ensure thread-unsafe, buggy, hard-to-maintain code!), it is to have each object "surface" those characteristics it is designed to maintain as part of its interface to clients going forward, instead of just letting poor clients go through such undending chains of nested refs!
This smells of an abstraction that may need some improvement. You seem to be violating the Law of Demeter.
In some cases a global isn't too bad.
Consider, you're probably programming against an operating system's API. That's full of globals, you can probably access a file or the registry, write to the console. Look up a window handle. You can do loads of stuff to access state that is global across the whole computer, or even across the internet... and you don't have to pass a single reference to your class to access it. All this stuff is global if you access the OS's API.
So, when you consider the number of global things that often exist, a global in your own program probably isn't as bad as many people try and make out and scream about.
However, if you want to have very nice OO code that is all unit testable, I suppose you should be writing wrapper classes around any access to globals whether they come from the OS, or are declared yourself to encapsulate them. This means you class that uses this global state can get references to the wrappers, and they could be replaced with fakes.
Hmm, anyway. I'm not quite sure what advice I'm trying to give here, other than say, structuring code is all a balance! And, how to do it for your particular problem depends on your preferences, preferences of people who will use the code, how you're feeling on the day on the academic to pragmatic scale, how big the code base is, how safety critical the system is and how far off the deadline for completion is.
I believe your question is revealing something about your classes. Maybe the responsibilities could be improved ? Maybe moving some code would solve problems ?
Tell, don't ask.
That's how it was explained to me. There is a natural tendency to call classes to obtain some data. Taken too far, asking too much, typically leads to heavy "getter sequences". But there is another way. I must admit it is not easy to find, but improves gradually in a specific code and in the coder's habits.
Class A wants to perform a calculation, and asks B's data. Sometimes, it is appropriate that A tells B to do the job, possibly passing some parameters. This could replace B's "getName()", used by A to check the validity of the name, by an "isValid()" method on B.
"Asking" has been replaced by "telling" (calling a method that executes the computation).
For me, this is the question I ask myself when I find too many getter calls. Gradually, the methods encounter their place in the correct object, and everything gets a bit simpler, I have less getters and less call to them. I have less code, and it provides more semantic, a better alignment with the functional requirement.
Move the data around
There are other cases where I move some data. For example, if a field moves two objects up, the length of the "getter chain" is reduced by two.
I believe nobody can find the correct model at first.
I first think about it (using hand-written diagrams is quick and a big help), then code it, then think again facing the real thing... Then I code the rest, and any smells I feel in the code, I think again...
Split and merge objects
If a method on A needs data from C, with B as a middle man, I can try if A and C would have some in common. Possibly, A or a part of A could become C (possible splitting of A, merging of A and C) ...
However, there are cases where I keep the getters of course.
But it's less likely a long chain will be created.
A long chain will probably get broken by one of the techniques above.
I have three patterns for this:
Pass the necessary reference to the object's constructor -- the reference can then be stored as a data member of the object, and doesn't need to be passed again; this implies that the object's factory has the necessary reference. For example, when I'm creating a DOM, I pass the element name to the DOM node when I construct the DOM node.
Let things remember their parent, and get references to properties via their parent; this implies that the parent or ancestor has the necessary property. For example, when I'm creating a DOM, there are various things which are stored as properties of the top-level DomDocument ancestor, and its child nodes can access those properties via the reference which each one has to its parent.
Put all the different things which are passed around as references into a single class, and then pass around just that one class instance as the only thing that's passed around. For example, there are many properties required to render a DOM (e.g. the GDI graphics handle, the viewport coordinates, callback events, etc.) ... I put all of these things into a single 'Context' instance which is passed as the only parameter to the methods of the DOM nodes to be rendered, and each method can get whichever properties it needs out of that context parameter.
A lot of times in code on the internet or code from my co-workers I see them creating an Object with just one method which only gets used once in the whole application. Like this:
class iOnlyHaveOneMethod{
public function theOneMethod(){
//loads and loads of code, say 100's of lines
// but it only gets used once in the whole application
}
}
if($foo){
$bar = new iOnlyHaveOneMEthod;
$bar->theOneMethod();
}
Is that really better then:
if($foo){
//loads and loads of code which only gets used here and nowhere else
}
?
For readability it makes sense to move the loads and loads of code away, but shouldn't it just be in a function?
function loadsAndLoadsOfCode(){
//Loads and loads of code
}
if($foo){ loadsAndLoadsOfCode(); }
Is moving the code to a new object really better then just creating a function or putting the code in there directly?
To me the function part makes more sense and seems more readible then creating an object which hardly is of any use since it just holds one method.
The problem is not whether it's in a function or an object.
The problem is that you have hundreds of lines in one blob. Whether that mass of code is in a method of an object or just a class seems more or less irrelevant to me, just being minor syntatic sugar.
What are those hundreds of lines doing? That's the place to look to implement object oriented best practice.
If your other developers really think using an object instead of a function makes it significantly more "object oriented" but having a several-hundred line function/method isn't seen as a code smell, then I think organisationally you have some education to do.
Well, if there really is "loads and loads" of code in the method, then it should be broken down into several protected methods in that class, in which case the use of a class scope is justified.
Perhaps that code isn't reusable because it hasn't been factored well into several distinct methods. By moving it into a class and breaking it down, you might find it could be better reused elsewhere. At least it would be much more maintainable.
Whilst the function with hundreds of lines of code clearly indicates a problem (as others have already pointed out), placing it in a separate instance class rather than a static function does have advantages, which you can exploit by rejigging your example a fraction:
// let's instead assume that $bar was set earlier using a setter
if($foo){
$bar = getMyBar();
$bar->theOneMethod();
}
This gives you a couple of advantages now:
This is a simple example of the Strategy Pattern. if $bar implements an interface that provides theOneMethod() then you can dynamically switch implementations of that method;
Testing your class independently of $bar->theOneMethod() is dramatically easier, as you can replace $bar with a mock at testing time.
Neither of these advantages are available if you just use a static function.
I would argue that, whilst simple static functions have their place, non-trivial methods (as this clearly is by the 'hundreds of lines' comment) deserve their own instance anyway:
to separate concerns;
to aid testing;
to aid refactoring and reimplementation.
You are really asking two questions here:
Is just declaring a function better than creating an object to hold only this function?
Should any function contain "loads of code"?
The first part: If you want to be able to dynamically switch functions, you may need the explicit object encapsulation as a workaround in languages that cannot handle functions this way. Of course, having to allocate a new object, assign it to a variable, then call the function from that variable is a bit dumb when all you want to do is call a function.
The second part: Ideally not, but there is no clear definition of "loads", and it may be the appropriate thing to do in certain cases.
yes, the presences of loads and loads of code is a Code Smell.
I'd say you almost never want to have either a block or a method with loads of code in it -- doesn't matter if it's in it's own class or not.
Moving it to an object might be a first step in refactoring 'though - so it might make sense in that way. First move it to its own class and later split it down to several smaller methods.
Well, I'd say it depends on how tightly coupled the block of code is with the calling section of code.
If it's so tightly coupled, that I can't imagine it being used anywhere else, I'd prefer sticking it in a private method of the calling class. That way it won't be visible to other parts of your system, guaranteeing it won't be misused by others.
On the other hand, if the block of code is generic enough (email validation i.e.) to possibly be interesting in other parts of the system, I'd have no problem extracting that part into it's own class, and then consider that to be a utility class. Even if it means it will be a single-method class.
If your question was more in the lines of "what to do with hundreds and hundreds of lines of code", then you really need to be doing some refactoring.
As much as a single method with lots of code is a code smell. My first thought was to at least make the method static. No data in the class so no need for creating an object.
I think i would look to rephrase the question that you are asking. I think you want to ask the questions is my class supporting singles responsibility principle. Is there anyway to decompose the pieces of your class into seperate smaller pieces that might change independently of each other (data access and parsing, etc . .). Can you unit test your class easily . .
If you can say yes to the above items, i wouldn't worry about method versus new class as the whole point here is that you have readable, maintainable code.
In my team we have red flag if a class gets long (over x amount of lines) but that is just a heuristic as if you class has 2000 lines of codes it probably can get broken down and is probably not supporting SRP.
For testability, it is definitely better to break it out into a separate class with separate method(s). It is a whole lot easier to write unit tests for single methods than as part of an inline if statement in a code-behind file or whatnot.
That being said, I agree with everyone else that the method should be broken out into single responsibility methods instead of hundreds of lines of code. This too will make it more readable and easier to test. And hopefully, you might get some reuse out of some of the logic contained in that big mess of code.
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 9 years ago.
Improve this question
What are those bad habits you've developed since you've started coding in Cocoa?
I think making a list of bad habits and actively adding to it and, more importantly, breaking those habits is a good technique to produce your code quality. So start now, get your bad habits off your chest. Maybe other people share your bad habits.
Passing nil to arguments that call for NSError**, pure lazy.
Not unit testing enough. It's really difficult to clean up and refactor code if you don't have unit tests. And without constant refactoring and cleaning, code rot begins to set in and spread.
Using the singleton pattern to share objects, like +[MyObject defaultObject]. This is essentially a global variable that makes for some nice hidden dependencies and coupling. This, in turn, makes code harder to test.
Using exceptions for control flow
(And other non-exceptional circumstances.)
Since use of exceptions is brought up in another answer here and the documentation referred to in the comments does not stress this point particularly, it is worth emphasising that exceptions should not be used for normal control flow (as is common in some other environments). Exceptions in Cocoa are comparatively extremely expensive. If you want to communicate an error, use an NSError object and the error-handling architecture provided by Cocoa. Don't throw exceptions.
Here's some of mine:
Throwing exceptions without any attempt to catch 'em. I've started to rely on NSError more and more to prevent NSExceptions from flying about like bullets in a John Woo movie, but I still have a lot of exceptional code out there.
Writing a quick class to do X, Y & Z and then forgetting to clean up in dealloc. Leaks ahoy!
Using strings directly in various places (KVO) instead of defining a constant and using that (see Dave Dribin's excellent blog post on KVO for more)
I get lazy about using accessors inside of classes. Usually, the biggest problem is that I can't easily tell the scope of the variable at a quick glance. Then I spent a few hours last week debugging a memory corruption issues that was due to using
self.displayName = name
in some places and
displayName = name
in others. I was happy when I found it and my app stopped crashing. I wasn't so happy that I wasted several hours looking for such an avoidable mistake.
I use #defines more often where I should be using const declarations.
Also, I'm probably a little too prolific in the NSNotifications I throw around; decoupling run amok!
Bad habit: Retaining my Java mindset.
My Java background leads me to obsessively check for a null before even thinking about doing anything with a variable, when I could be making use of Objective-C's ability to send a message to nil. (See: "Sending a message to nil?")
Instead of trying to preemptively catch a nil, I have to remind myself that Objective-C allows me to simply write code that gracefully works with return values of 0 or nil.
You mean, apart from grinning smugly when I can do in ten lines what takes an MFC coder 300? I suppose my biggest gripe about my own code is the explosion of accessors; next design work I do, I've set myself the challenge of using the smallest number of properties.
Misusing Bindings to bind model object properties to each other. This use of Bindings leads to code that is hard to understand, hard to debug, and hard to test. Use Bindings only to bind a UI to a Controller. If you need decoupled models, use NSNotification instead of bindings. At least it's a bit more explicit than KVO.
Hard-coding strings like buttons/view titles. Pure lazy. Now need to get out everything in order to support localization :(
I learned to hate Interface##$%-er back when it was far less useful and more buggy than it is now, and so tend to create all my UI in code, steadfastly still avoiding IB. It's silly, since I know it reduces my productivity a ton, but I just can't seem to be bothered to spend an afternoon learning how to plug things into IBs. (Yeah, I know how to do the simple stuff, but I always get annoyed when there's some medium-not-simple stuff to do, and IB seems to work against me.)
Ok, you convinced me -- I'm going to break THAT bad habit this weekend.
Thanks! :)
This is somewhat generic and not necessarily cocoa specific but:
Not refactoring enough because the laziness of having to update both .m and .h files.
XCode 3 makes it easier for certain kinds of refactoring like renames, but I found myself refactoring less frequently than on Java or C# and that's a bad habit I'm trying to break.
1) When using private global variables, start them with underscores and put them in the interface portion of the .m file like so:
#interface MyViewController (){
NSArray *_tableData;
NSNumberFormatter *_numberFormat;
}
2) Only use #properties for global public variables and/or interface elements.
3) Synthesize the global publics and call them by name.
4) Call your interface elements with self.labelTitle NOT _labelTitle.
The main reason I use these variable naming conventions is because I can easily look at a variable and know what it's used for and its scope, but mainly it's a work around for the bug in XCode where you try and refactor -> rename a variable across the project and it doesn't work in certain circumstances outside of this convention.
I refactor my variable names A LOT and this system alleviated a lot of the problems for me.
Other Quick Tips:
Use storyboard for everything that you possibly can, this alleviates the issues with code deprecation in new versions and it shrinks your total code base down significantly.
Name your controllers VCMyName (view controller), NCMyName (nav controller), TVMyName (tableview controller), etc. This is better than Apple's standard (MyNameViewController) because tacking on the full name at the end is often cut off due to being too long in a lot of interfaces. Interface builder interprets the recommended naming convention correctly, calling the views "My Name".
Learn and use Core Data, NOT your own make-shift SQLite querying system and create a helper unit for accessing data in one or two lines of code.
Do not put all of your shared app code in AppDelegate, that's not really what it's for, instead create an AppController unit and use the singleton pattern to access it in your views as needed.
Do follow Apple's convention of passing data forward to the next view controller and using delegates to handle returning data. This is much cleaner than storing globally accessible data somewhere.
Create a Constants.h (h file only) for your project where you can store contants used across your project, like standardized row heights, etc. There should be nothing but #define in this file.
Store login data in the key chain, that way it's more secure and if they delete the app and reinstall it completely, it's still there and you don't have to bug them with login requests.
Store custom user settings for your app in NSUserDefaults, this takes them out of your DB so that if you have migration/other issues this data (which is possibly the only data you can't reload from scratch in your app) isn't affected.
Pull requests from core data into dictionaries if you're passing them to a view, this keeps your core data entities out of your views and there's also a performance benefit.
Follow Apple's Cocoa conventions for variable and function names. When in doubt, always see if Apple has a convention for it.
These are just off the top of my head. Of course, some people may disagree with what I wrote but these habits worked for me when I was getting started.
I often find myself forgetting to type the return self; part of my constructors. Luckily I've begun to break this particular habit.