I read a lot of topics about principles for writing testable code. I'm working on using Dependency Injection in my application and I'm facing a very big problem.
In the top ViewController, I'm loading an array of objects and the user can select on of them to go deeper in the hierarchy. The thing is that I need the selected object in some controllers (including the leaf controller) and for some I don't need.
In picture, it can be like this :
NeedObject -> don't need -> don't need -> need
TopController -> otherController1 -> otherController2 -> leafController
For now, I'm passing the selected object through all the hierarchy, but I can feel how it's bad as it does not respect the principle stating that an object should only know about what it needs. But I can't figure out how to respect this principle.
Note that the objects are all children of ManagedObject and are stocked in CoreData.
I thought about adding like a boolean isSelected in the class definition and then use an object that would request CoreData for the object with selected = YES, but I'm not sure about it as the "selectability" of the object should not be something persistent, right ?
Thank you for your help
I think what you are doing already is fine.
As you have described it, otherController1 and otherController2 'need' a reference to the user selected object in order to pass that reference to a lower level controller.
Passing info down the hierarchy is the way to do dependency injection, even if some intermediate layers have no use for that information other than passing it on further.
This is preferred over having an object deep in the hierarchy "reaching back up" to a top-level object to request the information. Lower-level objects should know little about the higher-level objects, which gives you the most flexibility to evolve your hierarchy over time.
Apple recommends defining a protocol for passing dependency injection data this way, which further isolates dependencies between classes.
Related
Many CocoaPod and native iOS libraries use protocols that they name either CustomClassDelegate or CustomClassDataSource as a means to do some setup or customization. I was wondering when I should use this programming model, because it seems like I could accomplish much of this with properties.
Example
If I define a custom class called SmurfViewController that has a SmurfLabel, is it better practice to store the smurfLabel as a private property and have a public computed property called smurf that looks like this:
private var smurfLabel = UILabel()
public var smurf: String {
get {
return smurfLabel.text
}
set(text) {
smurfLabel.text = text
}
}
or should I define a SmurfDataSource that has a public function that looks like this:
func textForSmurfLabel() -> String {
return "smurfText"
}
When should I use what here?
You should just use a property for that. Delegates and Datasources are for different controllers/Objects to speak to one another when the alternative is to instantiate the controller/object from the navigationStack/view hierarchy. A Delegate forms a specific communication between the two that allows for clear knowledge in what their relationship is while keeping them decoupled (assuming you try to keep it that way). I disagree with the article that says callbacks are "better". They are amazing and I advise using them often, but just understand that most options that swift provides you with have a place where they work best.
I might be slightly bias, but Swift is an amazing language with OOP being a backbone and everything it has was well put together in order to provide the correct tools for each situation you find yourself in.
I often find myself using both of those tools and one other more customizable option in my more advanced setups where I have an overseeing viewController that manages many child controllers. It has direct access to all of them that are active but if any of its children communicate with it, it is through delegates. Its main job is just to handle their place on the screen though, so I keep everything manageable.
Delegates and data sources are more appropriate for offloading behaviors to other entities, not simple values. In other words, if your type just needs a value for something, you are correct that it makes more sense to expose that as a property that can be set from the client code.
But what should happen (for example) when a user taps a specific table view cell is a behavior that shouldn't be hard coded into UITableView. Instead, for flexibility, any implementation of that behavior can be created in a delegate and called by the UITableView when appropriate.
In general, think of delegation as a way to make subclassing unnecessary, because the methods you would normally override in a subclass are instead moved into a protocol that can be implemented by ANY type, not just a subclass of the base type. And instead of calling internally implemented methods to get certain behaviors, your type is simply calling those behaviors on an external collaborating class (the delegate).
So perhaps the best guideline for when to use a data source or delegate is the question: "Would I need to subclass this class in order to change this value or behavior in the future". If the answer is no, because you can just set a property from client code, then don't use delegation. If the answer is yes, then offload that behavior to a delegate or data source instead of forcing future programmers to subclass your class to make it work for their use case.
Delegate is an interface for the undefined activities.
so when you make a SDK or framework, you must provide an interface so that users can write a proper code for the interfaces' expecting activity.
i.e, Table View needs a datasource to show it's contents, but the apple's library developers doesn't know the content whatever contents their library users will use. so they provided an interface like datasource, delegate.
and in the library, they just call this methods. that's the way the library should be made.
But in your code, the label is defined very explicitly as well as it's in the current view, and you don't need to make an interface for an undefined activity.
if you want know more about this kind of coding style, you need to do some researches on Software Design Pattern.
https://en.wikipedia.org/wiki/Observer_pattern
https://en.wikipedia.org/wiki/Delegation_pattern
https://en.wikipedia.org/wiki/Software_design_pattern
I love apple's sdk very much, because they used all the needed design patterns very properly.
First of all i know MVC well and have been using it in project but when it comes to organizing classes and there role i am bit not sure of there proper implementation. Lets take a scenario to proceed with:
A sample which will display All Employee and Department. Data will be fetched from Web Services(Json) and will be stored as offline(Core Data).
So MVC pattern would be:
View will be my storyboard with Employee and Department UIViewController.
Controller will be EmployeeViewController.swift and DepartmentViewController.swift
Model will be Employee.swift and Department.swift
class Employee: NSObject {
var name: String?
}
class Department: NSObject {
var departmentName: String?
}
ServiceManager which will make calls to the web service.
ParseData which will parse the web service response and convert it into Employee and Department objects
CoreDataManager is singleton class to manage CRUD operation on offline DB.
Here are series of question on the above scenario which i have:
Is my understanding correct? Is the structure which i am trying to build follows proper MVC?
How the controller will interact with these components (Service Manager, ParseData, CoreDataManager). Should there be another class which will facilitate the communication between controller and data management(if controller does this then it will a tightly-coupled structure and massive as well).
Should Model be having any code other then property and initialization method as most of the model which i have seen only have property declaration?
Should there be separate UIView classes instead of storyboard to create a proper MVC structure?
Is my understanding correct? Is the structure which i am trying to
build follows proper MVC?
First I will say that "proper" MVC will depend on who you're asking. Its origin is commonly attributed to Trygve Reenskaug when he introduced this into Smalltalk in the 70's. However, his type of MVC was widely different from the bloated versions most commonly used today. The modern way of thinking about MVC is
Model = mostly a dumb class which primarily encapsulates data
View = whatever we present on the screen
Controller = the big lump of code that does almost everything,
sometimes offloaded by a manager class or two of some sort
Reenskaug, however, would have a model and a view and a controller for a button. For a label. For a field. I'm not saying that is what we should strive for, but there should be better ways to structure a project than using the Massive ViewController pattern (as it is jokingly referred to in the iOS community).
Luckily, there are.
Uncle Bob is preaching Clean Architecture. There are several implementations of this, and various people have made their own implementations of this for iOS, like VIPER and Clean Swift.
How the controller will interact with these components (Service
Manager, ParseData, CoreDataManager). Should there be another class
which will facilitate the communication between controller and data
management(if controller does this then it will a tightly-coupled
structure and massive as well).
Following the principles of Clean Architecture, you should encapsulate these functionalities into layers, in a way that enables you not just to split the code into multiple components, but also enables you to replace them with other components when that is needed. (But yes, at the very least avoid putting all of this in your controller!)
Should Model be having any code other then property and initialization
method as most of the model which i have seen only have property
declaration?
Again, there is not a single answer here. Some proponents of "real" OOP will say that each object should be self-served (i.e. a model object should know how to persist itself), while others extract the knowledge of such operations into "managers". Putting code to persist an object into the object could mean littering persistence functionality into many objects, or require you to rely on subclassing or other solutions to avoid this coupling.
Should there be separate UIView classes instead of storyboard to
create a proper MVC structure?
Storyboard or not does not determine whether you're using "proper" MVC. Also, what kind of class you're choosing (UIView or UIViewController) to represent the View is also not important. Your ViewController can be dumbed down to such a degree that it contains no logic (forwarding the logic that it DOES have to another class, i.e. the Presenter in VIPER).
I would recommend reading about the Clean Architecture and maybe watch a video of Uncle Bob explaining it, read other people's reports on implementing it, and then consider whether MVC is the correct pattern for your iOS project.
I have been doing iOS development using MVVM and dependency injection for a couple of months and I am really happy with the results. The code is so much clear and easier to test. But I have been stragling with a problem which I haven't found a solution that I felt really confortable with.
In order to understand the problem I want to give you a little bit of context. The last app that I have been working was architectured in the following way / layers:
Model
View models
View / View Controllers
Services: Classes that know how to deal with external services like Twitter, Facebook, etc.
Repositories: A repository is class that knows how to interact with a resource of the application's REST API. Lets say that we have a blog application, we could have the users resources and the posts resources. Each of thoses resources have several method. There is a 1-to-1 relation between the resources and the repositories.
When the applications starts we have a Bootstrap class that initializes the app and creates the main view model. We have a restriction that only view models can create other view models. For example in the case of having a view that contains a list of elements (in iOS it will be represented with a UITableView) and the detail view for each of thoses elements that is presented by pushing it to the navigation stack after tapping on the element in the list. What we do is make the view model that is attached to the table view controller create the detail view model. The table view controller listens to the table view model and then presents the detail view model by creating the detail view controller and passing it its view model. So the view controller does not know how to create a view model it only knows how to create a view controller for that view model.
Is the responsability of the parent view model to the pass all the dependecies to the child view model.
The problem comes when a view model that is very deep in the view hierachy needs dependencies that its parent controllers does not require. For example a service to access some external web service. Because its parent does not have that dependency it will have to add it to its dependecy list, thus adding a new parameter to the constructor. Imagine how this goes if the grand parent does not have the dependecy either.
What do you think is a good solution? Possible solutions:
Singletons: Harder to test and they are basically gloabl state
A factory class: We could a set of factory that knows how to create certain types of object. For example a ServiceFactory and RepositoryFactory. The service factory could have method to create services like: TwitterService, FacebookService, GithubService. The repository factory could know how to create a repository for each of the API resources. In the case of having a few factories (2 or 3) all the view models could dependent on this factories.
For now we have chosen the factory class solution because we don't need to use singletons and we can treat the factory as any other dependecy which makes it relatively easy to test. The problem is that it kind of feels like a good object and by having a factory you don't actually know which is the real dependecy that needs the view model, unless you look inside the constructor's implementation to check which factory methods are being called.
In our application, we have chosen to have our view models access their dependencies via dependency lookup rather than dependency injection. This means the view models are simply passed a container object which contains the necessary dependencies, and then "looks up" each dependency from this container object.
The major advantage of this is that all objects in the system can be declared up front in a container definition, and it is very simple to pass around the container, compared to the seventy-eight or so dependencies that might be needed.
As any dependency injection fan will tell you, dependency lookup is certainly its inferior cousin, largely because dependency lookup requires the object to understand the idea of a container (and therefore usually the framework that provides it), whereas dependency injection keeps the object blissfully unaware of where its dependencies came from. However, in this case I believe the tradeoff is worth it. Note that in our architecture, it's just the view models that make this tradeoff - all other objects such as your "models" and "services" still use DI.
It's also worth noting that many basic implementations of dependency lookup have the container as a singleton, but that does not have to be the case. In our application, we have multiple containers that simply "group" related dependencies together. This is particularly important if different objects have different lifecycles - some objects may live forever, while others may only need to live while a certain user activity is in progress. This is why the container is passed from view model to view model - different view models may have different containers. This also facilitates unit testing by allowing you to pass a container full of mock objects to the view model under test.
To provide some concreteness to an otherwise abstract answer, here's how one of our view models might look. We use the Swinject framework.
class SomeViewModel: NSObject {
private let fooModel: FooModel
private let barModel: BarModel
init(container: Container) {
fooModel = container.resolve(FooModel.self)!
barModel = container.resolve(BarModel.self)!
}
// variety of code here that uses fooModel and barModel
}
What you need to do is move the instantiation of all your objects to a Composition Root. Instead of parents passing down dependencies they don't even necessarily need to their children, you have a single point of entry at the start of your program where all of your object graph is created (and cleaned up, should you have Disposable dependencies).
You can find a good example here, by the author of the Dependency Injection in .NET book (highly recommended to understand concepts like the Composition Root) - notice how it frees you from having to pass dependencies 5 or 6 levels deep for no reason:
var queueDirectory =
new DirectoryInfo(#"..\..\..\BookingWebUI\Queue").CreateIfAbsent();
var singleSourceOfTruthDirectory =
new DirectoryInfo(#"..\..\..\BookingWebUI\SSoT").CreateIfAbsent();
var viewStoreDirectory =
new DirectoryInfo(#"..\..\..\BookingWebUI\ViewStore").CreateIfAbsent();
var extension = "txt";
var fileDateStore = new FileDateStore(
singleSourceOfTruthDirectory,
extension);
var quickenings = new IQuickening[]
{
new RequestReservationCommand.Quickening(),
new ReservationAcceptedEvent.Quickening(),
new ReservationRejectedEvent.Quickening(),
new CapacityReservedEvent.Quickening(),
new SoldOutEvent.Quickening()
};
var disposable = new CompositeDisposable();
var messageDispatcher = new Subject<object>();
disposable.Add(
messageDispatcher.Subscribe(
new Dispatcher<RequestReservationCommand>(
new CapacityGate(
new JsonCapacityRepository(
fileDateStore,
fileDateStore,
quickenings),
new JsonChannel<ReservationAcceptedEvent>(
new FileQueueWriter<ReservationAcceptedEvent>(
queueDirectory,
extension)),
new JsonChannel<ReservationRejectedEvent>(
new FileQueueWriter<ReservationRejectedEvent>(
queueDirectory,
extension)),
new JsonChannel<SoldOutEvent>(
new FileQueueWriter<SoldOutEvent>(
queueDirectory,
extension))))));
disposable.Add(
messageDispatcher.Subscribe(
new Dispatcher<SoldOutEvent>(
new MonthViewUpdater(
new FileMonthViewStore(
viewStoreDirectory,
extension)))));
var q = new QueueConsumer(
new FileQueue(
queueDirectory,
extension),
new JsonStreamObserver(
quickenings,
messageDispatcher));
RunUntilStopped(q);
Doing this is pretty much a prerequisite to do proper Dependency Injection, and it will allow you to very easily transition to use a container if you want to.
For the instantiation of objects that must be created after startup, or depend on data available long after startup, what you want to do is create Abstract Factories that know how to create these objects and take as constructor parameters all needed stable dependencies. These factories are injected as normal dependencies in the composition root, and are then called upon as needed with the variable/unstable arguments passed in as method parameters.
Here are a couple of suggestions.
Best coding practices suggests that if you are using more than 3 parameters, then you should use a class to host the parameters.
Another approach is to separate the data services [repositories] out, so that they line up to a task based service. Mainly to in line with the ViewModel (or Controller) So if you ViewModel uses Customers and Orders, most would use two services - one for CRUD operations on Customers, and one for CRUD operations on Orders. You could, however, use a service that will deal with all the operations needed for your ViewModel. This is a task based approach used in designing Windows Communication Foundation Services and Web Services.
It looks like you need to make use of the Managed Extensibility Framework (MEF), you can find more information here.
Essentially, what this will allow you to do is to use [Export] and [Import] attributes. This will allow your class' dependencies to be injected, without having to worry about massive constructors on your parent view models.
I am trying to implement component for possibility to apply different skins to views and controllers at runtime without reinitialising these controls. I want to use such logic:
Declare protocol with methods for applying skins.
All necessary classes implements this protocol.
When user selects skin all instances of classes that conform to protocol receive message to apply skin.
So I know how to get all necessary classes that conform to my specific protocol by using objc_getClassList and class_conformsToProtocol functions.
But how to get all allocated instances of these classes for sending message to them?
I know that it could be implemented by internal logic of every class by storing all instances in static storage and returning array by class method. But it isn't elegant solution. I'm finding more universal solution where I can add new skinnable controls in easy way.
It sounds very much like you're reinventing <UIAppearance>. You should at least start there. It's what it's for. Also see Peter Steinberger's writeup for discussion of adding custom properties.
To your basic question, there is not a runtime call to enumerate all allocated objects of a class. It would add a lot of overhead to provide that (objects come and go all the time and very quickly). Even if you could do it, you probably shouldn't. But since you're talking about visible views, then you can always do this by enumerating the view hierarchy under NSWindow. Any views not currently in the view hierarchy should be expected to correctly redraw in an new style the next time they come on the screen.
But I'd start with <UIAppearance>.
I'm currently working on a Rails project, and have found times where it's easiest to do
if object.class == Foo
...
else if object.class == Bar
...
else
...
I started doing this in views where I needed to display different objects in different ways, but have found myself using it in other places now, such as in functions that take objects as arguments. I'm not precisely sure why, but I feel like this is not good practice.
If it's not good practice, why so?
If it's totally fine, when are times that one might want to use this specifically?
Thanks!
Not sure why that works for you at all. When you need to test whether object is instance of class Foo you should use
object.is_a? Foo
But it's not a good practice in Ruby anyway. It'd much better to use polymorphism whenever it's possible. For example, if somewhere in the code you can have object of two different classes and you need to display them differently you can define display method in both classes. After that you can call object.display and object will be displayed using method defined in the corresponding class.
Advantage of that approach is that when you need to add support for the third class or a whole bunch of new classes all you'll need to do is define display method in every one of them. But nothing will change in places where you actually using this method.
It's better to express type specific behavior using subtyping.
Let the objects know how they are displays. Create a method Display() and pass all you need from outside as parameter. Let "Foo" know to display foo and "Bar" know how to display bar.
There are many articles on replacing conditionals with polymorphism.
It’s not a good idea for several reasons. One of them is duck typing – once you start explicitly checking for object class in the code, you can no longer simply pass an instance of a different class that conforms to a similar interface as the original object. This makes proxying, mocking and other common design tricks harder. (The point can be also generalized as breaking encapsulation. It can be argued that the object’s class is an implementation detail that you as a consumer should not be interested in. Broken encapsulation ≈ tight coupling ≈ pain.)
Another reason is extensibility. When you have a giant switch over the object type and want to add one more case, you have to alter the switch code. If this code is embedded in a library, for example, the library users can’t simply extend the library’s behaviour without altering the library code. Ideally all behaviour of an object should be a part of the object itself, so that you can add new behaviour just by adding more object types.
If you need to display different objects in a different way, can’t you simply make the drawing code a part of the object?