2

Say I have two views (Table View for example) that I'd like them to do different stuff; each loads different data but behaviors are similar for most par except what happens when a cell tapped for instance. One shows a list of entries, another a list of users, another a list of comments, etc. I can write one subclass of UITableViewControler for all with a flag variable to distinguish the logic or a separate sub class per each view controller.

I am trying to figure out what is best. I know smaller blocks are easier to debug, etc. But yet again, it's sort of repeating code to have multiple of the same class boilerplate. What would a good approach here?

  • It's unclear if you are trying to subclass the tableviewcontroller (which should be just a controller for the views in a tableview scene) or if you are subclassing two different views (where you need specific behavior/data for each view). Please clarify your question. – Tommie C. Mar 5 '17 at 12:13
  • @TommieC. Thanks, added some clarification in the first paragraph – TheeBen Mar 6 '17 at 14:55
1

The Open-Closed principle should be your guide here. Having a single UITableViewController subclass with a "flag variable" that is then checked all over the place inside the class is a very poor design choice. Every time you want to add a new table view controller in your app, you will end up having to dig into the MonsterTableViewController class and add yet another flag and a bunch of switch/if checks to handle the differences. Your class isn't "open for extension and closed for modification" that way.

If you find that you have, say, 3-4 different behaviors when a cell is tapped, but all the rest of the code is the same, then provide your view controller with a delegate or closure that represents the Strategy (à la the Strategy pattern) used when an item is tapped and provide that either at construction time, or if you are using a storyboard to construct, then in the previous prepare for segue.

You can even go so far as to make the strategy class generic and have it hold the array of objects that are used for the datasource. Then provide a closure for both the cellForRowAtIndexPath and the didSelect. Or you could go the more traditional route and make the strategy class a protocol and have several implementations.

Note this is very reminiscent of how UITableViewDatasource and UITableViewDelegate are already handled. What many people end up doing is just having a bunch of classes that implement both of those protocols. Pass an instance of one of those classes to the UITableViewController to handle the details.

2

You should try to have separate classes for each view controller, and a generic class (or more) for the common code, which will be reused by the specific classes. Avoid as much code repetition as you can.

Note: this is in no way special to ios, objective-c, swift or UITableViewController - it is a general principle in OO design.

  • Hi Doc, Thanks for your reply. I understand the general rule of thumb to avoid repetition. That why I started with one class for all the view Controllers that had similar operations such as various kinds of lists. But now that class has grown substantially and I'm thinking , wouldn't it be repeating the boilerplate of the same class though, if I were to break that into multiple classes, say, TableView Controller in this case? – TheeBen Mar 3 '17 at 10:31
  • @TheeBen: This sounds to me you better discuss this in terms of real code examples, which would lead to a question which will better fit on Stackoverflow.SE or Codereview.SE. – Doc Brown Mar 3 '17 at 12:40
  • copy and past boilerplate makes things worse, because now you have the same code on many places and you have to edit these in every class (and i will guess sometimes you forget one class). and you say: your common class is to big. if you extract each special use case in a separate sub classes – muescha Mar 28 '17 at 21:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.