I need to create a global object that will work and can be used across all the classes in the program. I've done some research and seen the solution seems to be implementing it in the AppDelegate, but there doesn't seem to be much explanation as to how to accomplish this and more importantly this doesn't really seem correct as per my understand of the AppDelegate purpose.
you should check the singleton pattern:
In software engineering, the singleton pattern is a design pattern
that restricts the instantiation of a class to one object. This is
useful when exactly one object is needed to coordinate actions across
the system. The concept is sometimes generalized to systems that
operate more efficiently when only one object exists, or that restrict
the instantiation to a certain number of objects. The term comes from
the mathematical concept of a singleton.
here is a source for a example implementation: What should my Objective-C singleton look like?
Related
I understand that delegates are essentially objects that another object can pass messages to, and that they are used on behalf of other classes. So for example, a UITableViewDelegate has methods which can be used to detect particular events in a UITableView. This is very useful, and indeed I have used delegates a lot in past iOS projects, so this is more of a curiosity:
Why do the methods in a delegate class not just exist in the class that the delegate is being delegated by?
Surely it would be more convenient to have those methods in the actual class, such as a UITableView?
Perhaps it is that architecturally it is more convenient, but from fist looks it seems counter intuitive.
As a general rule, composition is more powerful than inheritance. Inheritance creates many subtle problems, the most common of which is the diamond problem, but there are many other problems.
Delegation is just a specific formulation of the Strategy pattern, which allows us to extend an object via composition rather than inheritance.
As a concrete example of the issue, and how the diamond problem creeps in when you use inheritance, consider this:
You have a very common way you want to provide cells. For example, you'd like a Core Data fetch request, or a network request that generates cells. So you would build a superclass that encapsulated all this logic. We'll call the class that handles thatFetchRequestDataProviding.
Separately, you have a visual behavior you use a lot. For example, you want a particular kind of animations for your view, so you wrap that up into a class FadeInTableView.
Now we have a problem because we want both. So we need multiple inheritance. And multiple inheritance is Pandora's box of ambiguities.
But I eliminate all of that if I make FetchRequestDataProviding a separate object that behaves as a delegate. I actually could make things even more powerful by breaking out FadeInAnimating as a delegate/strategy (though UIView doesn't have that power today).
In ObjC, "composition is more powerful than inheritance" shows itself commonly in a fairly shallow inheritance tree and lots of delegates. Swift pushes this further with protocols and structs that have no inheritance. None of this means that inheritance is bad; it can have a lot of value (though languages like Go avoid it entirely; though interestingly still has to face the diamond problem due to embedding). But when in doubt, composition is the more powerful tool.
With swift, isn't it possible to dump functions and variables into a file instead of implementing a singleton? Is there a good reason (like memory management or something) that I am missing, other than style concerns?
It is very much possible to do so. Module level private variables could be used as private variables for singleton class.
For me it is rather a choice dictated by what makes more sense as a solution to the problem. The language has given us tools each with its particular usage, so use them the way they are meant to be used.
If your solution requires an object with data, state and related functionality which could have only one instance then it is better to use a singleton. This will make more sense when you or someone else will try to understand code at later time.
If your solution is just bunch of loosely related functions without data or state then it is better to use functions in a file.
With swift, isn't it possible to dump functions and variables into a file instead of implementing a singleton?
Yes, it is definitely possible. However, the same is possible in Objective-C, with the same pluses and minuses.
Is there a good reason (like memory management or something) that I am missing, other than style concerns?
Two considerations are relevant here:
You can make your singleton polymorphic, expose an interface, define several implementations, and pick the specific one at runtime
You can "reset" your singleton by discarding the instance and creating a new one.
If you need concurrency, having a singleton makes it a little easier to implement.
I commonly create apps that require storage of data, and this data is used across the entire program. It's not much, though, so I usually use NSUserDefaults to load/save this data. However, the saving/loading code, along with packing/unpacking the data, takes up space, and I thought moving this code to reusable methods inside a global singleton would be a good idea. It seems to have worked well.
Even so, I've read a lot lately on the evils of singletons and global objects, and I've started to have second thoughts. People often say that the use of singletons is almost always an indications of poor design. For the most part, I'd disagree (I think simple uses like this are a good design pattern), but I'm certainly no expert on the matter.
So, is using singletons even in a simple way like this bad? If so, what's the better alternative?
I definitely don't agree that singletons are evil. They are sometimes overused perhaps but on some occasions are just perfect for the job. In some applications it makes sense to have some kind of general data manager. The singleton pattern is used extensively in the SDK itself (app delegates, shared managers, default centers and so on). Most often these are not "pure" singletons, as in you can access a shared instance but can also create new instances if necessary.
The question you need to ask yourself is whether it would be useful to have access to a single instance of a data manager from anywhere at anytime, if it isn't then a singleton is probably not needed. If you are going to be using singletons in multi-threaded environments however, you do need to worry about race conditions (can one thread modify a resource while another is accessing it), the documentation has good explanations on how best to achieve this in Cocoa.
Let me try to explain with an example - Am using some code from a game I wrote. Let's say you have a GameMap class and a Tile class. The GameMap represents a 2 dimension grid of Tile objects.
GameMap *gameMap = [[GameMap alloc] init];
NSArray *theTiles = gameMap.tiles;
The instance of the GameMap owns the grid of tiles, and creates the tiles when the game map is created. No singleton needed.
You may say "but I only have one GameMap at a time, what's the big deal?". What about loading saved games, or loading new levels? Well that becomes as easy as:
// In whatever class object owns the game map
self.gameMap = [[GameMap alloc] initWithSaveData:saveData];
In conclusion, create an instance of a class that has code to manage other instances of things. Keep as little global as possible and your code will be more scalable and maintainable.
A best practice in DI I've read in a few places is not to inject object B just to get at object C, but to inject C instead.
But if a single method from C is all that is required, would you just inject that method instead of C?
If so, what about if a few methods from C were required? Is there a point that it's just more convenient to pass in the full object and live with the fact that you're getting stuff you have no interest in?
Or does that point indicate that maybe class C has too many varied responsibilities and needs to be extracted into multiple smaller classes, the objects of which can then be injected without as much baggage?
Don't be afraid to state the obvious, this is all new to me.
If the dependency has (many) more methods than you care about, it's a pretty good sign that it's a Header Interface that violates the Interface Segregation Principle.
If you have control over the interface, I'd suggest splitting it up into several smaller Role Interfaces. You can still have one concrete class implementing more than one Role Interface if that makes more sense for your specific implementation.
If you don't control the design of the dependency, I'd tend towards injecting the whole interface, as it still represents a cohesive collection of behavior (even if we don't agree with the design choice of the original designer). You might need more of that behavior later on.
Or it's better to use another Design Pattern?
Responded to a similar question some days ago here, mocking a Singleton. The original post is for C#.Net as regards mocking a singleton's behaviour, but should still apply.
As regards the singleton pattern, there isn't anything wrong with it per se - in many cases we want to centralize logic and data. However, there is a very big difference between a singleton and a static class. Building your singleton as a static class hard codes that implementation to every consumer in your application - which makes unit testing very difficult!
What you want to do is define an interface for your singleton, exposing the methods for your consumers to use. Your consumers in turn are passed a reference to an implementing class by whomever instantiates them [typically this is your application, or a container if you are familiar with Dependency Injection\Inversion of Control].
It's this framework, whomever is instantiating the consumers, that is responsible for ensuring one and only one instance is floating around. It's really not that great a leap from static class to interface reference [as demonstrated in link above], you just lose the convenience of a globally accessible instance - i know i know, global references are terribly seductive, but Luke turned his back to the Dark Side, so can you!
Generally speaking, best practices suggest avoiding static references, and encourages progamming against interfaces. Remember, it is still possible to apply the singleton pattern with these constraints. Follow these guidelines, and you should have no problem unit testing your work :)
Hope this helps!
singleton != public static class, rather singleton == single instance
Lack of testability is one of the major downfalls of the classic Singleton model (static class method returning an instance). As far as I'm concerned, that's justification enough to re-design any code that uses Singletons to use some other design.
If you absolutely need to have a singular instance, then Dependency Injection and writing to an interface, as suggested by johnny g, is definitely the way to go.
I'm using the following pattern when I write a static-based singletons that I can mock. The code is Java, but I think you will get an idea. The main problem with this approach is that you have to relax constructor to package-protected (which sorta defeats a true singleton).
As a side note - the code applies to ability to mock your "static" code not necessarily simply calling it
I generally only use Singletons for Flyweight objects or similar value objects. Looking into an IoC container (as discussed above) is probably a better way to handle a shared object than a singleton.
Consider that in Smalltalk (where a lot of these patterns originated), true and false were both effectively singletons :)
If you must use a singleton (and there are reasons to do so...but I would always try to avoid it if possible). I would recommend using a IOC container to manage it. Im not sure if there is one for Delphi or not. But in Java you could use Spring, in .NET you can use Windsor/Castle. A IOC container can hold onto the Singleton and can register different implementations for testing.
It's probably too big of a subject to get into here beyond this snippet.