Consequences of Singletons - iphone

So I just delved into the Singleton classes and yes, I find them quite helpful. I use my singletons mostly for data storage for multiple targets (views, tables etc.). That being said, I can already see myself going to implement a lot of singletons in my project.
But can a lot of singletons have a negative impact? From what I've read about singletons is that you create one instance for each of them in a proces. Other class instances get released (assuming they get released properly) from memory, then should singletons be released too?
So to narrow it down to one question: Is it harmful to have a lot of singletons?

Singletons don't scale. No matter what you think should be a singleton, when your system gets bigger, it turns out you needed more than one.
If you NEVER need more than one, a singleton is fine. However, as systems scale, you typically need more than one of anything within its own context.
Singletons are merely another way to say "global". It's not bad, but generally, it's not a good idea for systems that evolve and grow in complexity.

From GOF Book:
The Singleton pattern has several benefits:
Controlled access to sole instance. Because the Singleton class encapsulates its sole instance, it can have strict control over how
and when clients access it.
Reduced name space. The Singleton pattern is an improvement over global variables. It avoids polluting the name space with global
variables that store sole instances.
Permits refinement of operations and representation. The Singleton class may be subclassed, and it's easy to configure an application
with an instance of this extended class. You can configure the
application with an instance of the class you need at run-time.
Permits a variable number of instances. The pattern makes it easy to change your mind and allow more than one instance of the Singleton
class. Moreover, you can use the same approach to control the number
of instances that the application uses. Only the operation that grants
access to the Singleton instance needs to change.
More flexible than class operations. Another way to package a singleton's functionality is to useThe Singleton class can be
subclassed. class operations (that is, static member functions in C++
or class methods in Smalltalk). But both of these language techniques
make it hard to change a design to allow more than one instance
ofclass. Moreover, static member functions in C++ are never virtual,
so subclasses can't override them polymorphically.

Related

what are the practices to avoid a class becoming a god class?

Let us take an example of a Consumer class. The functions related to a Consumer will go into this class. Gradually the Consumer class has lot of methods in it. And those are supposed to be part of the Consumer class itself. In such cases, how do we break it? are there any strategies related to solving this?
This is quite a broad question but I'll attempt to answer it.
SOLID principles are good practices to follow. If you apply these, especially the Single Responsibility Principle, you will end up with smaller classes with well defined responsibilities.
It's also important to look at cohesion which is a measure of how related the elements of your class are. You want to aim for high cohesion in your classes (and modules). For example, if every method in your class uses a certain member variable, then cohesion is high. If there is a member variable of your class which is only used in one method, this is a good case to be refactored into a separate class.
Use structural design patterns. I would use either the Composite or Decorator design pattern to address your issue. You can learn about them here: https://sourcemaking.com/design_patterns/structural_patterns
As already exposed by #MoonMoo the guidelines for refactoring a fat class should be SOLID principles and cohesion of classes.
The point is: even if a method is related to a Customer, should it stay in Customer class? Or that method can be called by the Customer from another class?
The answer to these question could be a first starting point to understand which methods must stay in the Customer class and which methods can be relocated in another form in another class to which the Customer has a reference.

When and why use anonymous class instead of stucts for simple objects

I read in this answer A generic list of anonymous class how to load a list with anonymous class objects. My question is why and when is recommendable to use this way instead of using a struct, considering performance and good practices.
An exposed-field structure is essentially a group of variables bound together with duct tape. It won't behave as an "object", and may thus be seen as evil who think everything should behave like an object; nonetheless, in cases where one doesn't really want an object, but rather a group of variables bound together with duct tape, an exposed-field structure may be a perfect fit.
Anonymous classes have only a few advantages over exposed-field structures:
The syntax to declare them is at least slightly smaller; depending upon coding standards, it may be a lot smaller. If coding standards will allow one to write internal struct WeightAndVolume { public double weight, volume;} and say that the struct is "self-explanatory" [it contains two public fields of type double, named weight and volume, each of which will hold whatever was last written to it by outside code], anonymous classes won't save much, but if coding standards would require that every named data type have many pages of associated documentation, including an analysis of required unit-test procedures, anonymous classes could avoid such hassle.
Copying class references is slightly cheaper than copying structures larger than 8 bytes, though unless a reference would be copied many times, the cost of creating the object will outweigh any savings in copying.
Casting an anonymous class to Object is much cheaper than casting a struct. The first time an anonymous class instance gets cast to Object will make up for the extra costs of creating it. Every additional time will represent a savings of that amount.
Passing a structure to a generic method will require the JITter to produce a specialized version of the code for that type; by contrast, the JITter would only have to produce one piece of code to handle all anonymous classes.
In general, structures will work better than anonymous classes. On the other hand, there are a few scenarios (mostly related to the third point above) where classes can end up being much better.
I wouldn't say it is ever recommended to use anonymous classes, in the sense that it's never wrong to not use them. But they typically get used when
it's an one-shot job, for which creating a proper named type would be cumbersome, and
the consumer of the objects is either compiler-generated code (you don't have access to the types backing those anonymous classes, but the compiler does) or uses reflection (in which case you don't need access to the types at compile time)
The most common scenario where this occurs is in LINQ queries.

how to get all instances of a given class/trait with scala reflect? all refs to a given instance?

I know it's possible to get the members of a class, and of a given instance, but why is it hard to get all instances of a given class? Doesn't the JVM keep track of the instances of a class? This doesn't work in Java:
myInstance.getClass.getInstances()
Is this possible with the new scala reflect library? Are there possible workarounds?
Searched through the reflection scaladoc, on SO and google, but strangely couldn't find any info on this very obvious question.
I want to experiment/hack a hypergraph-database, inspired by hypergraphDB, querying the object graph directly, set aside serialization.
Furthermore, I'd need access to all references to a given object. Now this information certainly is there (GC), but is it accessible by reflection?
thanks
EDIT: this appears to be possible at least by "debugging" the JVM from another JVM, using com.sun.jdi.ReferenceType.instances
"Keeping track" of all instances of a class is hardly desirable, at least not by default. There's considerable cost to doing so and the mechanism must avoid hard references that would prevent reclaiming otherwise unreferenced instances. That means using one of the reference types and all the associated machinery involved.
Garbage Collection does not need to be class-aware. It only cares about whether instances are reachable or not.
That said, you can write code to track instantiations on a class-by-class basis. You'd have to use one of the reference classes in java.lang.ref to track them.

What, if any, are the negative consequences of basing a Model layer on NSManagedObject?

I've been doing iOS now for about two years and mostly by consequence of simple data layers (no real need for ID's, joins, complex queries, etc), I've always managed persistence manually by extending NSObject, conforming to NSCoder, and saving my data in flat files.
However, now I am in a position where I need to start doing more complex query work and I am digging into CoreData.
My hangup right now is with NSManagedObject. It's a pretty intimidating class and I am wondering if there are any unwritten gotchas I should be aware of that might restrict my freedom while building a sophisticated application.
For example, things like #dynamic getter/setters are not to clear to me, etc
So:
1) Are there any features of NSManagedObject that would prevent me from handling instances of custom classes just as I would with NSObject?
2) Does NSManagedObject have any unusual behavior when objects are handled WITHOUT the presence of a ManagedObjectContext?
3) Can I supplant a #dynamic property declaration with my own custom getter/setter without too much pain? I use a lot of custom setters to enforce business logic.
and so on, and so on.
Thanks
Beware!
Core Data is not lightweight. It will require a lot of changes to the way your objects work, unless they are very basic.
1) Are there any features of NSManagedObject that would prevent me from handling instances of custom classes just as I would with NSObject?
Faulting and the lifecycle of managed objects are a little tricky to understand. Your objects can be "faulted" almost at any time (each iteration of the event loop anyway), which makes them lose any non-persistent state. When they get "un-faulted", they don't have access to anything outside the managed object context to restore their state. It's very hard for managed objects to access anything outside the managed object context.
Transient properties are possible, but are pretty much limited to things that can be computed from the persistent properties, since their state will be lost if the object is ever faulted. You also have to formally declare that you're using a transient property in the data model. Trying to just set up instance variables will run into problems.
So basically managed objects properties all must be persistent or related to persistent properties. Look at the objects you're planning to make managed. Are all their instance variables feasible and desirable to put into a persistent store? If not things will not be straightforward. You probably set up your instance variables in your init. There is no init that gets called every time your program runs for managed objects. There are awakeFromInsert and awakeFromFetch, but those don't work exactly like init. Your code calls init and can pass arguments. The framework calls awake and it gets no parameters.
Threading is another issue to consider. A managed object context, and therefore the managed objects in it, are recommended to be used only by a single thread. If you have multiple threads, and they need to access your model, you need to create duplicate managed object contexts containing duplicates of your managed objects. Core Data is designed to handle that without putting too much strain on memory, disk I/O, and processor, but it isn't lightweight from a coding perspective.
2) Does NSManagedObject have any unusual behavior when objects are handled WITHOUT the presence of a ManagedObjectContext?
You cannot have a managed object without a managed object context.
That's not usually an issue. Managed objects carry a pointer to their managed object context. It can be a little limiting though. If something outside your model needs to create a model object as an input to your model, it needs to have access to the managed object context to do that. Hopefully that would be through some kind of abstraction layer so it doesn't need to know it's dealing with Core Data, but you can't just give it a class and have it alloc/init. It is also a bit of work to move managed objects between different managed object contexts.
3) Can I supplant a #dynamic property declaration with my own custom getter/setter without too much pain? I use a lot of custom setters to enforce business logic.
Yes. It's a bit complicated but doable. You write your own accessors. In addition to your business logic, they must call key-value observing methods like willChangeValueForKey:. Then you access the data using primitive accessors.
1) Are there any features of NSManagedObject that would prevent me from handling instances of custom classes just as I would with NSObject?
Creating and removing them is different, but not difficult. Otherwise, no
2) Does NSManagedObject have any unusual behavior when objects are handled WITHOUT the presence of a ManagedObjectContext?
I'm not sure what you mean, you can pass a managed object to another class and use it quite happily without the other class knowing about the context, but you must have a context somewhere.
3) Can I supplant a #dynamic property declaration with my own custom getter/setter without too much pain? I use a lot of custom setters to enforce business logic.
Yes, NSManagedObject is designed for this purpose. There are plenty of examples of overridden accessors in the core data programming guide - there are some rules you need to follow but they are not too onerous.
Core data is primarily a persistence framework rather than a query framework - I imagine once you get into it you will wonder why you were wasting your time on all those NSCoding implementations...
1) Are there any features of NSManagedObject that would prevent me
from handling instances of custom classes just as I would with
NSObject?
No. You can extend a NSManagedObject subclass just like a NSObject subclass.
2) Does NSManagedObject have any unusual behavior when objects are
handled WITHOUT the presence of a ManagedObjectContext?
The #dynamic directive will create accessors optimized for saving in a persistent store managed by a context. The values will still be available just like any other object but you will generate a lot of overhead.
3) Can I supplant a #dynamic property declaration with my own custom
getter/setter without too much pain? I use a lot of custom setters to
enforce business logic.
You can but you will incur some performance penalty because the generated accessors will be highly optimized for the specific code in your app.
One major point of novice confusion with regard to managed object is missing that the generic NSManagedObject can represent any entity in the data model without subclassing. NSManagedObject has "associative storage" which basically means that it has an open dictionary attached to it that save any key-value pairs. When you you insert a generic NSManagedObject into a context, the keys of the associative storage "dictionary" are set to the property names of the entity given.
Therefore, you are actually never really forced to subclass NSManagedObject. Doing so is largely a matter of convenience.
That is why you sometimes see code that uses generic NSManagedObject and the setValue:forKey and other times you see custom subclasses that use anObject.propertyName.
I would also advise that if you find yourself using or saving managed object outside a context, then chances are good that you have a bad design.

Is it good practice to use AppDelegate for data manipulation and Handling?

I am making an object of AppDelegate and using it throughout my program, and I have declared all setters and getters, and also insert, select, delete, update queries of database in it.
I want to ask that is it a good practice to do so,
if yes, then how, and if no then why it is not a good practice?
I hope my question is clear, please ask relating questions if you have any.
It's not a good strategy to turn your AppDelegate into a "big ball of mud" that contains a million methods and properties (although it might be tempting).
A better and more object oriented approach to section off bits of functionality into well-designed objects -- for example you might have a class DatabaseManager which handles all database interactions. You might then have bits of your app which need the DatabaseManager ask the app delegate instance for a reference to a DatabaseManager.
Alternatively, you can pass around a reference to the DatabaseManager to the parts of the app that need it. This last approach does however cause more 'interface pollution', where you have to modify interfaces in lots of places in order to pass in the DatabaseManager.
And yet another alternative would be to effectively make your DatabaseManager itself be a 'singleton' -- whereby an instance of it is accessed via a class method on the class. Singletons that work in this way are often frowned upon, and usually for good reasons (makes testing harder, that sort of thing). I tend to avoid having objects have their 'singleton' nature baked right into the object -- I prefer, if I need that sort of thing, to have a known point of access (a kind of 'factory' if you like) where you can go to obtain a shared instance.
I think the best way would be creating a global singleton class instead of handling in the Appdelegate.
Declare all you setters and getters there and using the singleton object handle all around your project. See this link how to create singleton class
For Database, create a DataAccessLayerClass. whenever you want to execute any queries access this class. This class methods should have inputs as your data and will create the queries and will execute that query and return the data.
It's all about complexity and your feelings. You must like your solution ;-)
I obviously do this in another way - I've got singleton, which does handle all my common database things. I'm trying to keep application delegate as simple as possible. It's better for code sharing, etc.