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.
Related
In Chapter 2: Meaningful Names Uncle Bob writes:
Don't Add Gratuitous Context
In an imaginary application called "Gas Station Deluxe," it is bad idea to prefix every class with GDS. Frankly, you are working against your tools. You type G and the press completion key and are rewarded with a mile-long list of every class in your system
Actually that what I discovered during my first days with Objective-C a bit more than one year ago. After Java it was quite disappointing but I thought I'm only one who annoyed about that :)
I understand, that "Clean Code" book refers to Java most of the time and Java has namespaces (packages) unlike Objective-C.
Do you use 2-3 letters prefix in your classes if you're building an app, not a library?
What do you think, is it bad language design, language "feature" or Uncle Bob wasn't right here?
Perhaps the key word here is gratuitous. In Objective-C, prefixes serve the important purpose of reducing the chance of name collisions. In other languages like Java and C++, the existence of support for namespaces makes the use of prefixes gratuitous (and a violation of the oft-cited DRY principle). In Objective-C, however, prefixes are meaningful, useful, and not gratuitous.
I was tempted to close this question, but I don't think I've seen a similar one asked before and it's a valid question. Here are my rather disorganized thoughts on the matter.
Many languages have a feature called namespaces, where the "fully qualified" class name is prefixed by a hierarchical series of names. For example, the String class in Java is, properly, java.lang.String, and a custom class is properly com.whatever.foobar.MyClass.
Unfortunately, namespaces have never been added to Objective-C, which means that Objective-C symbols (class names, protocol names, and a few various other types) cannot be placed in a namespace even when using Objective-C++ (which has a namespace feature for functions, constants, structures, etc.)
The only solution to prevent symbol collisions in shared code, then, is to use some form of name mangling to make your symbol names unique. In Objective-C, the convention is to use a prefix of two characters (sometimes the number varies) for all your classes.
This Uncle Bob fellow is a twit for telling you not to do this, because while you'll end up with a program that doesn't compile, you'll lose any benefit of namespaces that prefixes still offer. Does your app use plugins? You need to prefix. Does your app have a public API? You need to prefix.
In theory, code within a single application that never touches the outside world can do without prefixes, but screw it--keep coding cleanly, and add a prefix even there. It'll save you grief later.
Personally I almost never use prefixes. The only exceptions are classes that are somehow connected to each other or they all should be present.
An example:
Some client app for chat. Let's call that chat an ExampleChat.
Then I'd use ECMessage, ECUser, ECRoom, etc. to easily see which classes should there be.
Or if I make some custom cells for UITableView I'd use prefixes to keep them all close to each other and not struggle with searching them in a "mile-long list". Example:
ECTextMessageCell, ECSoundMessageCell, ECUploadMessageCell, ECJoinOrLeaveMessageCell, etc.
That's my personal opinion, which can not be the best. But it's still easiest for me.
Hope it helps
Well if you do not have Namespaces, name conflicts are likely to occur. You can see that in a lot of C libraries that they are using some kind of prefix. So I guess there are good reasons to have those prefixes and other reasons not to use it. But what should be the big problem to modify the completion to either just ignore the prefix of typing three letters instead of just one.
So in the end it seems to me a matter of taste. I guess it would be more important to have good structures classes with prefixes instead of a mess of classes without prefix....
It has nothing to do with bad language design IMHO. There was a time where software was not everywhere and why should one waste extra effort on namespaces? And still as we can see even nowadays languages without namespaces are used.....
I would say, that the world is not black or white. I do programming in java, with packages and yes, it is annoying to have a prefix in each class, as well as it is annoying and arguable to start interfaces with I (just like .Net used to do it).
Sometimes it does annoying me in objective-c however it has some legitimacy if you do not have packages in your language, since you can 'build' artificial groups of classes like 'NS', 'UI', 'MK' and so on in objc and cocoa.
Beyond avoiding collisions, one of the benefits that name prefixes gives is that you're immediately aware of what type you're really dealing with. Suppose you had the following code:
Color c = ...;
MultiValueMap m = ...;
From a cursory glance at the code and depending on what libraries you've used, those types could be from a number of different sources. You may have to lookup which include/import statement was made to understand what the type can do (e.g. you want to modify it but it's missing a method that you're sure is there).
In the iOS world, you would immediately know whether it's a UIColor vs. a CGColor and gain immediate context.
In the past at WWDC, Apple would host a session where they explained Cocoa/Objective-C coding conventions. I believe they mention this aspect of name prefixes so you might want to find one of the recordings that are made available. Other C developers (e.g. Linux kernel developers) also do not seem to think highly of C++ namespaces (among other C++ features) for various reasons.
I have spent the last couple of hours reading about the singleton pattern and why not to use it, amongst others those really good sites:
Singleton I love you, but you're bringing me down
How to Think About the "new" Operator with Respect to Unit Testing
Where have all the Singletons Gone?
I guess quite a lot of you know these already.
Looking at my code after reading that, I clearly am one of the maybe 95% of programmers that misunderstood and misused the singleton pattern.
For some cases, I can clearly remove the pattern, but there are cases where I am unsure what to do:
I know singletons for logging are accepted, one reason for that being that information only flows into them but not back into the application (just into the log file or console etc of course).
What about other classes which do not meet that criteria but are required by a lot of classes?
For example, I have a settings object which is required by a lot of classes. By a lot, I mean more than 200.
I have read into some other SO questions like "Singletons: good design or a crutch?", and all of them pointed out why using singletons is discouraged.
I understand the reasons for that, but I still have one major question:
How do I design a class which needs a single instance, accessible from everywhere, if not using the Singleton pattern?
The options I can think of would be:
Use a static class instead (though I don't see how this would be any better, looking at OOP and unit testing).
Have it created in an ApplicationFactory and perform dependency injection on every single class that needs it (keep in mind it's 200+ for some cases).
Use a singleton anyway, as the global access bonus outweighs the disadvantages for that case.
Something completely different.
It will depend on exactly what you mean by a settings object.
Do all 200 classes need all the settings; if not why do they have access to the unused settings?
Where do the settings come from and is there a good reason why each class can't load its settings as and when required?
Most importantly though, don't make changes to working code just because the code uses a pattern which is frowned upon. I've only used the singleton pattern once but I'd use it again.
EDIT:
I don't know your constraints but I wouldn't worry about multiple access from a file until it had been shown to be an issue. I would split up the configuration into different files for different classes/ groups of classes or, preferably, use a DB instead of files with different tables providing data for each class.
As an aside I've noticed that once you put the data in a db people seem to stop worrying about accessing it multiple times even though you're still going to the file system in the end.
PS: If other options aren't suitable I'd use a singleton... you want data to be globally available, you're not willing to use dependency injection, you only want the file to be read once; you've limited your options and a singleton isn't that bad.
Isn't this already discussed extensively and exhaustingly?
There is no misuse of the pattern. If your software works as expected (inlcuding maintainability and testablility) you are right with singletons.
The thing about people complain is that the singleton pattern has more impact than only restrict a class to have a single instance.
you introduce a global variable
you cannot build a subclass
you cannot reset the instance
If all this is not a problem for you: Use singletons all over the place. The pattern discussion is academic and hairsplitting.
And - to answer your question - checkout the monostate vs singleton thread: Monostate vs. Singleton
I wanted to ask you all for you opinions on code smells in Objective C, specifically Cocoa Touch. I'm working on a fairly complex game, and about to start the Great December Refactoring.
A good number of my classes, the models in particular, are full of methods that deal with internal business logic; I'll be hiding these in a private category, in my war against massive header files. Those private categories contain a large number of declarations, and this makes me feel uneasy... almost like Objective-C's out to make me feel guilty about all of these methods.
The more I refactor (a good thing!), the more I have to maintain all this duplication (not so good). It just feels wrong.
In a language like Ruby, the community puts a LOT of emphasis on very short, clear, beautiful methods. My question is, for Objective C (Cocoa Touch specifically), how long are your methods, how big are your controllers, and how many methods per class do you all find becomes typical in your projects? Are there any particularly nice, beautiful examples of Classes made up of short methods in Objective C, or is that simply not an important part of the language's culture?
DISCLOSURE: I'm currently reading "The Little Schemer", which should explain my sadness, re: Objective C.
Beauty is subjective. For me, an Objective-C class is beautiful if it is readable (I know what it is supposed to do) and maintainable (I can see what parts are responsible for doing what). I also don't like to be thrown out of reading code by an unfamiliar idiom. Sort of like when you are reading a book and you read something that takes you out of the immersion and reminds you that you are reading.
You'll probably get lots of different, mutually exclusive advice, but here are my thoughts.
Nothing wrong with private methods being in a private category. That's what it is there for. If you don't like the declarations clogging up the file either use code folding in the IDE, or have your extensions as a category in a different file.
Group related methods together and mark them with #pragma mark statements
Whatever code layout you use, consistency is important. Take a few minutes and write your own guidelines (here are mine) so if you forget what you are supposed to be doing you have a reference.
The controller doesn't have to be the delegate and datasource you can always have other classes for these.
Use descriptive names for methods and properties. Yes, you may document them, but you can't see documentation when Xcode applies code completion, where well named methods and properties pay off. Also, code comments get stale if they aren't updated while the code itself changes.
Don't try and write clever code. You might think that it's better to chain a sequence of method calls on one line, but the compiler is better at optimising than you might think. It's okay to use temporary variables to hold values (mostly these are just pointers anyway, so relatively small) if it improves readability. Write code for humans to read.
DRY applies to Objective-C as much as other languages. Don't be worried about refactoring code into more methods. There is nothing wrong with having lots of methods as long as they are useful.
The very first thing I do even before implementing class or method is to ask: "How would I want to use this from the outside?"
I never ever, never begin by writing the internals of my classes and methods first. By starting of with an elegant public API the internals tend to become elegant for free, and if they don't then the ugliness is at least contained to a single method or class, and not allowed to pollute the rest of the code with it's smell.
There are many design patterns out there, two decades of coding have taught me that the only pattern that stand the test of time is: KISS. Keep It Simple Stupid.
Some general rules of thumb, for any language or environment:
Follow your gut feeling over any advice you have read or heard!
Bail out early!
If needed, verify inputs early and bail out fast! Less cleanup to do.
Never add something to your code that you do not use.
An option for "reverse" might feel like something nice to have down the road.
In that case add it down the road! Do not waste time adding complexity you do not need.
Method names should describe what is done, never how it is done.
Methods should be allowed to change their implementation without changing their name as long as the result is the same.
If you can not understand what a method does from it's name then change the name!
If the how part is complex enough, then use comments to describe your implementation.
Do not fear the singletons!
If your app only have one data model, then it is a singleton!
Passing around a single variable all over the place is just pretending it is something else but a singleton and adding complexity as bonus.
Plan for failures from the start.
Always use for doFoo:error instead of doFoo: from the start.
Create nice NSError instances with end user readable localized descriptions from the start.
It is a major pain to retrofit error handling/messages to a large existing app.
And there will always be errors if you have users and IO involved!
Cocoa/Objective-C is Object* Oriented, not **Class Oriented as most of the popular kids out there that claim to be OOP.
Do not introduce a dumb value class with only properties, a class without methods performing actual work could just as well be a struct.
Let your objects be intelligent! Why add a whole new FooParser class if a fooFromString: method on Foo is all you need?
In Cocoa what you can do is always more important than what you are.
Do not introduce a protocol if a target/action can do.
Do not verify that instances conforms to protocols, is a kind of class, that is up to the compiler.
My 2 cents:
Properties are usually better than old-style getter+setter. Even if you use #dynamic properties - declare them with #property, this is way more informative and shorter.
I personally don't simulate "private" methods for classes. Yes, I can write a category somewhere in the .m(m) file, but since Obj-C has no pure way to declare a private method - why should I invent one? Anyway, even if you really need something like that - declare a separate "MyClassPrivate.h" with a category and include it in the .m(m) files to avoid duplicating the declarations.
Binding. Binding for most Controller <-> UI relations, use transformers, formatters, just don't write methods to read/write controls values manually. It makes code look like something from MFC era.
C++, a lot of code look much better and shorter when written in C++. Since compiler understands C++ classes it's a good point for refactoring, especially when working will a low-level code.
I usually split big controllers. Something more than 500 lines of code is a good candidate for refactoring for me. For instance, I have a document window controller, since some version of the app it extends with image importing/exporting options. Controller grows up to 1.000 lines where 1/2 is the "image stuff". That's a "trigger" for me to make an ImageStuffController, instantiate it in the NIB and put all image-relative code in there.
All above make it easier for me to maintain my code. For a huge projects, where splitting the controllers and classes to keep 'em small results big number of files, I usually try to extract some code into a framework. For example, if a big part of the app is communicating with external web-services, there is usually a straight way to extract a MyWebServices.framework from the main app.
I am creating a simple application using the MVC design pattern where my model accesses data off the web and makes it available to my controllers for subsequent display.
After a little research I have decided that one method would be to implement my model as a singleton so that I can access it as a shared instance from any of my controllers.
Having said that the more I read about singletons the more I notice people saying there are few situations where a better solution is not possible.
If I don't use a singleton I am confused as to where I might create my model class. I am not over happy about doing it via the appDelegate and it does not seem viable to put it in any of the viewControllers.
any comments or pointers would be much appreciated.
EDIT_001:
TechZen, very much appreciated (fantastic answer as always) can I add one further bit to the question before making it accepted. What are your thoughts on deallocating the singleton when the app exits? I am not sure how important this is as I know quite often that object deallocs are not called on app teardown as they will be cleared when the app exits anyway. Apparently I could register the shared instance with NSApplicationWillTerminateNotification, is that worth doing, just curious?
gary
There is a lot of push back on the use of singletons because they are often abused. Lazy coders either (1) don't put enough functionality in the singleton which results in having logic spread out in other objects like spaghetti or (2) they put in to much functionality such that the singleton becomes the entire program. Lazy coders way to often use singletons instead of doing data validation, object testing and object tracking. People get sick of trying to untangle and maintain lazy singleton use so they try to suppress the use of singletons.
I thoroughly understand the impulse and I myself ritualistically warn against singleton abuse.
However, a data model is one of the few legitimate uses for a singleton. This is especially true in small apps like those which run on mobiles. In the end, you will either use a singleton for your data model or you will attach it to a singleton.
For example, suppose you decide to park your non-singleton data model object in the app delegate. Well, you've done this: dataModel-->appDelegate-->application(singleton). To access it, you would call:
[[[UIApplication sharedApplication (a singleton)] delegate] theDataModelObj];
Even if you pass it around like a token from object to object you will still have to have the dataModel obj begin as the property of a singleton.
When an object really does have to meet the "Highlander" pattern ("There can be only one!") then a singleton is the best choice. In addition to the application object, you have user defaults as a singleton as well as the file manager. Clearly, in all three cases, you want one and only one instance in existence for the entire app. For example, if you had more than one user defaults object, your app would be a train wreck trying to track all the preference settings. If you have more than one file manager, file operations could step on one another.
A properly designed user data model is just a larger version of user defaults. It should be the only object that directly manipulates the user's data. No other object in the app should have that task in the least. That makes the singleton design pattern the best one to use in this particular case.
Singletons are a very powerful tool but just as with a physical tools, the more power they give you, the more opportunities they create for you to cut you head off if you use them carelessly. For this reason, a singleton should seldom be your first choice. There are usually better design patterns to employ.
However, when you really need a singleton, you shouldn't shy away from using them just because the laziness of others has given them a bad rep.
Knowing when and when not to use a powerful and dangerous tool is part of the programmers intuition you develop with experience. You can't go by formula. It is one of those factors that makes good coding an art and the programmer a craftsman.
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.