I have a few ViewControllers in my storyboard. Lets call them:
SB_VC1
SB_VC2
SB_VC3
I have one ViewController.swift file. Within that file, I have multiple ViewController classes, let's call them:
VC_Class_1
VC_Class_2
VC_Class_3
Each VC_Class is used as its corresponding SB_VC's class. Each VC_Class has different code, tailored to what I want the SB_VC to do.
These are all on the same hierarchy level, none is a subview of another. They each inherit from UIViewController and import UIKit and CoreData.
Question:
Part 1
Is keeping the code for all three classes in one file wrong? Should I be creating a new file for each VC_Class? Or is this just a matter of personal preference? If it is not preference and is clearly wrong, what is the problem it causes?
Part 2
If all three do have a little bit of overlap, in terms of each having a few functions that are the same, should I create a fourth class and call it something like "ToolBox.swift" and use it to call those functions? Or would it be better to have VC_Class_1 house those functions and make VC_Class_2 and VC_Class_3 inherit from VC_Class_1?
Generally, it is a matter of preference. Though I'd highly advise against it. Large files are harder to maintain, and it will take you longer and longer to find pieces of code you need. It will also be easier for other people to read and undestand your code.
As for the common code, it depends on its nature. You can either create a Toolbox class or a superclass from which you will inherit.
Related
I'm making a method inside a Ruby on Rails app called "print" that can take any string and converts it into a png. I've been told it's not good to make class methods for base ruby classes like String or Array or Hash, etc. so "some string to print".print is probably not something I should do.
I was thinking about making a subclass of String called Print (class Print < String) and storing it in my lib/assets folder. So it would look like: Print.new("some string to print"). So my question is, am I on the right track by 1) creating a sub-class from String and 2) storing it in lib/assets?
Any guidance would be greatly appreciated!
Answers to your question will necessarily be subjective because there are always be many answers to "where should I put functionality?", according to preference, principle, habit, customs, etc. I'll list a few and describe them, maybe add some of my personal opinions, but you'll ultimately have to choose and accept the consequences.
Note: I'll commonly refer to the common degenerate case of "losing namespacing scope" or "as bad as having global methods".
Monkeypatch/Extend String
Convenient and very "OO-message-passing" style at the cost of globally affecting all String in your application. That cost can be large because doing so breaks an implicit boundary between Ruby core and your application and it also scatters a component of "your application" in an external place. The functionality will have global scope and at worst will unintentionally interact with other things it shouldn't.
Worthy mention: Ruby has a Refinements feature that allows you to do do "scoped monkeypatching".
Worthy mention 2: Ruby also lets you includes modules into existing classes, like String.class_eval { include MyCustomization } which is slightly better because it's easier to tell a customization has been made and where it was introduced: "foo".method(:custom_method).owner will reveal it. Normal Monkeypatching will make it as if the method was defined on String itself.
Utils Module
Commonly done in all programming languages, a Util module is simply a single namespace where class methods/static methods are dumped. This is always an option to avoid the global pollution, but if Util ends up getting used everywhere anyways and it gets filled to the brim with unrelated methods, then the value of namespacing is lost. Having a method in a Util module tends to signify not enough thought was put into organizing code, since without maintenance, at it's worst, it's not much better than having global methods.
Private Method
Suppose you only need it in one class -- then it's easy to just put it into one private method. What if you need it in many classes? Should you make it a private method in a base class? If the functionality is inherent to the class, something associated with the class's identity, then Yes. Used correctly, the fact that this message exists is made invisible to components outside of that class.
However, this has the same downfall as the Rails Helper module when used incorrectly. If the next added feature requires that functionality, you'll be tempted to add the new feature to the class in order to have access to it. In this way the class's scope grows over time, eventually becoming near-global in your application.
Helper Module
Many Rails devs would suggest to put almost all of these utility methods inside rails Helper modules. Helper modules are kind of in between Utils Module and Private Method options. Helpers are included and have access to private members like Private Methods, and they suggest independence like Utils Modules (but do not guarantee it). Because of these properties, they tend to end up appearing everywhere, losing namespacing, and they end up accessing each other's private members, losing independence. This means it's more powerful, but can easily become much worse than either free-standing class/static methods or private methods.
Create a Class
If all the cases above degenerate into a "global scope", what if we forcibly create a new, smaller scope by way of a new class? The new class's purpose will be only to take data in and transform it on request on the way out. This is the common wisdom of "creating many, small classes", as small classes will have smaller scopes and will be easier to handle.
Unfortunately, taking this strategy too far will result in having too many tiny components, each of which do almost nothing useful by themselves. You avoid the ball of mud, but you end up with a chunky soup where every tiny thing is connected to every other tiny thing. It's just as complicated as having global methods all interconnected with each other, and you're not much better off.
Meta-Option: Refactor
Given the options above all have the same degenerate case, you may think there's no hope and everything will always eventually become horribly global -- Not True! It's important to understand they all degenerate in different ways.
Perhaps functionality 1, 2, 3, 4... 20 as Util methods are a complete mess, but they work cohesively as functionality A.1 ~ A.20 within the single class A. Perhaps class B is a complete mess and works better broken apart into one Util method and two private methods in class C.
Your lofty goal as an engineer will be to organize your application in a configuration that avoids all these degenerate cases for every bit of functionality in the system, making the system as a whole only as complex as necessary.
My advice
I don't have full context of your domain, and you probably won't be able to communicate that easily in a SO question anyways, so I can't be certain what'll work best for you.
However, I'll point out that it's generally easier to combine things than it is to break them apart. I generally advise starting with class/static methods. Put it in Util and move it to a better namespace later (Printer?). Perhaps in the future you'll discover many of these individual methods frequently operate on the same inputs, passing the same data back and forth between them -- this may be a good candidate for a class. This is often easier than starting off with a class or inheriting other class and trying to break functionality apart, later.
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>.
Is it ok to create dependencies between categories in Objective C? Also between the categories and their base class?
I know that there should be no difference at runtime, they probably are just merged together at compile-time. For instance, let us say i break down my class B into:
B(base class)
B+categ1
B+categ2
B+categ3
My question is, is it wrong to either:
a) import B+categ2 and B+categ3 in B.m
b) import B+categ1 in B+categ3?
I'm asking both performance-wise and conceptually.
EDIT:
What would you suggest for a single screen app? Categories or Extending that class?
There's nothing deeply wrong with it, but it may suggest an overuse of categories. While they are a powerful tool for certain problems, and definitely can create some conveniences, I generally wouldn't build a complex system on them.
I usually find that overuse of categories is based on too much IS-A thinking rather than HAS-A thinking. In other words, if you're putting a lot of categories on an class to act as a fancy kind of subclassing, you may be better off using composition instead. Rather than adding lots of category methods to NSArray (as an example), you would want an data object that has an NSArray property and provides the interface you want.
But this is just advice if you're overusing categories. There's no fundamental problem with having categories import other categories. However, this claim is incorrect:
I know that there should be no difference at runtime, they probably are just merged together at compile-time.
Categories are resolved at runtime, not compile-time. The one major danger of that is that if two categories implement the same method, then the behavior is undefined. This is why you should never use categories to override methods, only to add them.
Avoid having a base class depend on a category of itself. Exceptions to this rule are made for private categories (use extensions instead) and categories intended to be used by subclasses of the base class. These are specialized exceptions and should not be thought of as a proper general purpose solution.
For categories depending on categories, if you make sure the dependency graph never has a cycle, then you should be fine.
As a final bit of advice, be explicit about dependencies.
// A+c2
#import "A+c1.h" // A(c2) relies on A(c1) declared methods/properties.
…
// A+c3
#import "A+c1.h" // A(c3) relies on A(c1) declared methods/properties.
#import "A+c2.h" // A(c3) relies on A(c2) declared methods/properties.
Even though A(c3) is implicitly including A(c1) by importing "A+c2.h", I still explicitly import it. This will save frustration as code changes in the future.
I've inherited a long term maintenance code base that has two radically different iPhone and iPad views. This has created one large UIViewController class that has ballooned to over 1k lines of code, is a mashup of ISIPAD statements, private vars, properties, iBOutlets/Actions and, for example, uses a UITableView for one implementation and something completely different for another.
To make matters worse the current software pattern relies on subclassing.
Currently we look like this:
ParentVC (both iphone/ipad God class also has xib(xib~ipad) + iboutlets/actions)
| | |
ChildA ChildB ChildC
My initial thought was to take the ParentVC and split it into iPhone/iPad specific classes
ParentVCBase
| |
ParentVC_iPad(xib~ipad) ParentVC_iPhone(xib)
| |
ChildA/B/C_iPad ChildA/B/C_iPhone
and spit out the correct Child subclass via a factory call.
The issue I've encountered is that each Child overrides a few ParentVC method calls and implements it's own feature specific methods that are not device specific (keep in mind the main goal of the original subclassing was to share view layout). This design pattern would only work if I were to duplicate code for ChildA_iPhone and ChildB_iPad. I'd rather avoid that as I've traded one anti-pattern for another.
I'm a at a bit of a loss here. I've almost considered creating the Child classes at runtime (objc/runtime.h), swizzeling the required Child methods from a reference Child class but that doesn't seem any less of a mess than we currently have. To simply clean up I've also considered keeping the ParentVC header (with it's large list of IBOUTlets, properties, etc) and putting device specific methods into categories to at least separate the functionality until the day a real refactor is needed.
Curious if there are any iOS architects that have had to deal with this at one point in time or how they might deal with it.
This isn't an iOS specific question as much as it is a object-oriented design question.
You definitely want to avoid code duplication. Duplication is the source of much evil.
In general, what you want do is avoid being restricted by the limitations of inheritance in designing your classes. What you want to move towards is class composition.
So you could move to a design that looks like this using the bridge pattern:
ParentVC ---> ImplementationA
| | | |
ChildA ChildB Implementation_iPhone Implementation_iPad
Here, ParentVC has the same class hierarchy as above, but it uses a separate class hierarchy, ImplementationA, for implementation. That class hierarchy breaks down into iPhone and iPad versions. Class ImplementationA holds the guts of the implementation that was in ParentVC.
Inheritance is a design pattern, but it is just one of many. If you stick to just using that one pattern you'll get stuck into making bad designs. You need to combine patterns to properly model the system.
Of course, be sure to use unit tests, as much as possible, to ensure you don't break anything when you're making these changes.
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?