Any reason not use use a singleton "variable" in Swift? - swift

For Sept 2015, here's exactly how you make a singleton in Swift:
public class Model
{
static let shared = Model()
// ( for ocd friends ... private init() {} )
func test()->Double { print("yo") }
}
then elsewhere...
blah blah
Model.shared.test()
No problem.
However. I add this little thing...
public let model = Model.shared
public class Model
{
static let shared = Model()
func test()->Double { print("yo") }
}
then, you can simply do the following project-wide:
blah blah
model.test()
Conventional idiom:
You see Model.shared.blah() everywhere in the code.
"My" idiom:
You see model.blah() everywhere in the code.
So, this results in everything looking pretty!
This then, is a "macro-like" idiom.
The only purpose of which is to make the code look pretty.
Simplifying appearances of ImportantSystem.SharedImportantSystem down to importantSystem. throughout the project.
Can anyone see any problems with this idiom?
Problems may be technical, stylistic, or any other category, so long as they are really deep.
As a random example, here's an "article in singletons in Swift" that happens to also suggest the idea: https://theswiftdev.com/swift-singleton-design-pattern/

Functionally, these are very similar, but I'd advise using the Model.shared syntax because that makes it absolutely clear, wherever you use it, that you're dealing with a singleton, whereas if you just have that model global floating out there, it's not clear what you're dealing with.
Also, with globals (esp with simple name like "model"), you risk of having some future class that has similarly named variables and accidentally reference the wrong one.
For a discussion about the general considerations regarding globals v singletons v other patterns, see Global Variables Are Bad which, despite the fairly leading title, presents a sober discussion, has some interesting links and presents alternatives.
By the way, for your "OCD friends" (within which I guess I must count myself, because I think it's best practice), not only would declare init to be private, but you'd probably declare the whole class to be final, to avoid subclassing (at which point it becomes ambiguous to what shared references).

There are a few things to look out for when using this approach:
The global variable
A global variable in itself is no big deal, but if you have quite some global variables, you might have trouble with autocompletion, because it will always suggest these global variables.
Another problem with global variables is that you could have another module in your application (written by you or otherwise) define the same global variable. This causes problems when using these 2 modules together. This can be solved by using a prefix, like the initials of your app.
Using global variables is generally considered bad practice.
The singleton pattern
A singleton is helpful when working with a controller, or a repository. It is once created, and it creates everything it depends on. There can be only one controller, and it opens only one connection to the database. This avoids a lot of trouble when working with resources or variables that need to be accessed from throughout your app.
There are downsides however, such as testability. When a class uses a singleton, that class' behaviour is now impacted by the singletons behaviour.
Another possible issue is thread safety. When accessing a singleton from different threads without locking, problems may arise that are difficult to debug.
Summary
You should watch out when defining global variables and working with singletons. With the appropriate care, not many problems should arise.

I can't see a single downside to this approach:
You can use different variables for different parts of the program (-> No namespace cramming if you don't like this I guess)
It's short, pretty, easy to use and makes sense when you read it. Model.shared.test() doesn't really make sense if you think about it, you just want to call test, why would I need to call shared when I just need a function.
It uses Swift's lazy global namespace: The class gets allocated and initialized when you use it the first time; if you never use it, it doesn't even get alloced/inited.
In general, setting aside the exact idiom under discussion, regarding the use of singletons:
Recall that, of course, instead of using static var shared = Model() as a kind of macro to a singleton, as suggested in this Q, you can just define let model = Model() which simply creates a normal global (unrelated to singletons).
With Swift singletons, there has been discussion that arguably you want to add a private init() {} to your class, so that it only gets initialized once (noting that init could still be called in the same file).
Of course in general, when considering use of a singleton, if you don't really need a state and the class instance itself, you can simply use static functions/properties instead. It's a common mistake to use a singleton (for say "calculation-like" functions) where all that is needed is a static method.

Related

Best Practices: description vs debugDescription

Headline: description called by super.init()
This is a new take on an old question. As a primarily Swift programmer I tend to not use NSObject for class definitions because of the residual side effects of Objective-C. Like if I have a read-only property called length and I then want to create a setter function called setLength, I get warnings about it conflicting with a similar definition from Objective-C. I just discovered the set(var){} setter. If I subclass a Cacoa class like UIDocument, etc. that inherit from NSObject, I have to live with these side effects.
I have a class that uses two other classes in the property definitions, none of them NSObjects. This class has a description computed variable that uses the description computed variables for the other two classes in its composition. All three classes need to conform to the CustomStringConvertable protocol. Ok, everything is good.
At some point this class got upgraded to being a UIDocument and the CustomStringConvertable became redundant and was removed. Everything still works.
Here is what I found out today. I wanted to break at a point in the program where it was printing one of the two properties and as a convenience I set the break point in the description variable for that class, thinking that it should only be called at the point I am interested in, where it is printed out. What I discovered is that the description variable gets called during all the super.init() of the UIDocument sub-class! And there were a few of them. I think composing strings as being relatively expensive but didn't care because they were only used in debug, but with them being called and who knows how they are used in super.init(), I need to change this.
I checked another UIDocument class in the same program that has 200 files associated with it and it is also calling description in super.init().
Does anyone have any input on the Best Practices for using description vs debugDescription?
I'm going to answer my own question as a matter of documentation.
I switched the UIDocuments subclasses to define and use debugDescription. I am debugging some code that loads all the files and does some manipulation and I was able to reduce the load time from 9.8 seconds to 6.8 seconds.
I also went through all the places where the Swift 3 conversion added String(describing:) to the program and found I could change a lot of them to using debugDescription and eliminate the String(describing:) wrapper.
I think the best practice is to only define and use debugDescription and for my non-NSObjects change conformance from CustomStringConvertable to CustomDebugStringConvertable.

Swift: refactor singleton pattern

I have a Swift singleton class that maintains app state by storing several arrays. What is the best practices' way to go here? Should we change it, and if we do, then how?
Here is the singleton class:
import Foundation
class FilterModel {
static let sharedInstance = FilterModel()
private init() { }
var muscleExercisesArray = [Int]()
var equipmentExercisesArray = [Int]()
var typeExercisesArray = [Int]()
}
If you're wondering about the basic singleton pattern, a couple of observations:
I might suggest you declare the class to be final, too, to avoid having some future developer subclass it and introduce confusion about to what type sharedInstance refers.
I might also suggest that in Swift 3, the convention is to simplify the name of sharedInstance to just shared. It's not a hard and fast rule, but is the emerging standard.
This implementation is not thread-safe. If you're ok with that, I'd at least include some warning in the comments warning future developers of this concern. Or, obviously, with a little work you could change this to be thread-safe by wrapping this all in some internal synchronization mechanism.
You said:
Singletons are considered a bad approach towards app architecture, so I was wondering what to do instead of it when we need to maintain app state. Somehow I can not find anything online except for DI approach that does not work (or I do not know how) in this case when we need app state to be modified by different files
Yes, singletons are not ideal for model objects for a number of reasons (makes unit testing harder; makes responsibilities unclear, etc.) and there are better patterns (see What's Alternative to Singleton). At the very least, one simple approach is to have app delegate or root view controller instantiate this model object and then only pass this to whatever subsequent controllers need access to it (e.g. in prepareForSegue). This way, it's explicit which objects might be interacting with the model, making responsibilities a little more clear.

In Swift OOP design, how do I arrange a commonly-used class?

I am new to Swift and OOP. For example, I have a class that manages the system-wide configurations.
class system_conf {
init()
getValue1()
getValue2()
...
setValue1()
setValue2()
...
reloadValues()
activateX()
activeteY()
...
}
This class should have only one instance and many other classes will use it. What's the recommended way for this case?
Should I pass around this instance?
Should I consider to use Singleton?
Should I use static functions directly?
Should I create a global instance, so every other class can access it directly?
or?
It seems your class is a configuration class. If you intend to pass it to a bunch of classes, you should wonder if you need to write unit tests for them.
If so, assuming you are either using a singleton or static methods or a global var, take a moment to think about how you would mock this configuration class for each of your tests. It's not easy, is it?
If your class is a kind of mediator, a global var or static methods are fine (or any other alternative you suggested). However, in your case, it would be better to pass your object in any initializer/constructor of each class using it. Then, testing would definitely be easier. Also, passing it via an interface is even better: you can mock it super easily (mock up libraries mostly work with interfaces only).
So there is no unique answer to your question. It is just a matter of compromises and scaling. If your app is small, any of the method you listed above is perfectly fine. However, if you app tends to get bigger, a proxy solution would be better for maintainability and testability.
If you fancy reading, you should glance at this article from Misko Hevery, especially this chapter.

Are static classes and methods bad? Global variables frowned upon?

I have an application that has database connectivity and although there are obviously objects that correspond to data in my database, I find that all my data processing methods could be static as there is no real need for an instance of the object as my classes simply operate on the data and spit something out, no need to store anything outside the method's scope. If I can make a method or class static should I?
Also I use a utility singleton class for common (single instance) "global data". I want to have a good design, but are these frowned upon?
Let me give you an example of what I'm doing. I load some data from my database using a static method to place it into a global varaiable in my Singleton class (a list of a custom object)
So my singleton class has something like
List<MyCustomObject> SomeList
and my static class has
static void LoadData()
foreach(data in database something or other)
singletonClass.SomeList.Add()
So the code above might load in some records from the database into SomeList, where each item in SomeList is of type MyCustomObject, which contains a single record of information.
Is this good implementation? Is this how you would code it?
Then in my presentation layer I would make calls to another static class of methods to get data from the singleton class in to a format required.
It doesn't feel very OOPey. But I can't really think how to do it another way you do it.
Allow me to direct you toward an excellent article on this topic: Singletons are Pathological Liars.
The problem is that the need to call your LoadData() function isn't self-evident. Compare your situation to that described in the article and I think you'll see some parallels.
Statics and singletons are frowned upon somewhat. But only the same way as starting a sentence with “but” — bad when overused, but sometimes it's what works best.
In your example, why have separate classes, one a singleton and one static? A singleton is in many ways equivalent to a class with only static data and methods. If you already have a singleton, I'd say you should add the methods to load the data to it rather than to a separate class. A class with static methods would be more appropriate if, say, you have utility code common to all of your stored data types.
(Also, I wouldn't worry too much about what's OOPey and what's not. Overengineering in the blind service of OOP principles can be a serious problem, speaking as someone who's had to wade through the Eclipse code base …)
Singletons is one but static is another very big one.
OOP or not, static variables have many drawbacks but little coding convenience.
Can't determine exact allocation time, life span
Can't work well in multi-threaded
Future problem to program expansion
...

Classes: Public vars or public functions to change local vars?

Exactly what the topic title says,
In which cases would you prefer using public functions to change local variables over just defining that variable as public and modifying it directly?
Don't expose the data members directly: using opaque accessors means you can change the implementation at a later date without changing the interface.
I should know. I take the short cut from time-to-time, and have had occasion to regret it.
Obviously if you want changing the variable to have some other effect on the object's state (like recalculating some other property of the object) you must use a mutator function.
If it's possible to set the variable to something that places the object in an invalid state, you should probably also use a mutator function. This way you can throw an exception (or return an error, or just ignore) if something illegal is about to happen. This does wonders for debugging.
But if some variables can be modified with mutator functions, and others are public, the programmer needs to keep track of which is which. This is a waste of time and effort so in some cases it's easiest to just use mutator functions for everything.
If you look at an object purely in term of service, you realize that exposing a variable is not a good way to expose those services.
The API must reflect what the object is all about (for it to achieve a high cohesiveness), and if you define a setValue(...), it is not so much because you need a way to -- today -- changes a variable, but because it makes sense for the object to expose this service.
So:
Don't provide accessors or mutator function to every single member of every single class you write. Only provide accessors/mutator functions if the accessors/mutator methods are a sensible and useful part of the class's interface (API).
Don't think of these methods as accessors or mutators. Instead, think of them as methods that access or mutate a certain abstract property of the object that happens to be represented by a single member today, but may be computed in a more complex manner tomorrow.
You should mention what language you are dealing with, since that will affect the answer.
Your first thought should be about the API to your class. If you want to keep that API stable (and you should!), then consider how you might change today's simple variable into a full-blown method later.
In many languages, you can't change a variable to a method without changing the calling code. C, C++, and Java fall into this category. Never use public variables in these languages, because you won't have any wiggle room later.
In Python, you can change a variable to a property without changing the callers, so you don't have to worry up front: use public variables.
C# I believe has properties that can let you change variables to methods transparently, but I am not sure.
If you want to change a variable inside a class, your best doing it through Properties.
Its not good practice to have variable's modified on the outside.
Think of future development too. You could put some logic behind a Property without changing the whole program.