Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Upcoming SlideShare
Socrates15 - Clean Code
Socrates15 - Clean Code
Loading in …3
×
1 of 42

Writing clean code

3

Share

Download to read offline

Writing Clean code. Presentation given in the iOSX Summit 2014 (Amsterdam)

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

Writing clean code

  1. 1. Writing clean code Mobiquity - Ángel García (Mobile developer)
  2. 2. What is all this about?
  3. 3. Table of contents • What is clean code? • Why is readability important? • Code style • Code formatting • Naming conventions • Code comments • Code structure • Control sentences • Functions and methods • Classes • Architecture level • Modules • Software patterns • Programming paradigms • Tools
  4. 4. Before we start A bit of context
  5. 5. • No universal definition ! • Difference between clean code, working code and good code • Clean code: readable, maintainable, extensible • Working code: does what it is supposed to do • Good code: combination of clean and working code What is clean code? Working code Clean code Good code
  6. 6. Why is readability important? • The process of changing code: 1.Find component 2.Find affected lines 3.Write 4.Test ! • Reading —> 80/20 ! • Readability: • Save your time • Improve maintenance • Increase extensibility
  7. 7. Code formatting ReAD Ing iS nO t Al Wa iS aS E as Y As IT cO uLd bE
  8. 8. Code formatting {"id":10,"childs":[{"id":1,"title":"A"},{"id":2,"title":"B"}],"active": true,"title": "Hello World”} { "id": 10, "childs": [ { "id": 1, "title": "A" }, { "id": 2, "title": "B" } ], "active": true, "title": "Hello World" }
  9. 9. Code formatting • Brain is good on recognising patterns • Vertical space • Horizontal space • Expressions • Casing ! • Text search along project ! • Follow language styles ! • Be consistent
  10. 10. Naming conventions What the hell does this mean?
  11. 11. Naming conventions • The importance of naming. What does this code do? ! func doMyStuff(param1: Bool, param2: Bool, param3:Int) -> Int { if param3 > 0 { var a = 0 if param3 % 2 == 0 && param2 { a = param3 } else if param3 % 2 == 1 && param1 { a = param3 } return a + doMyStuff(param1, param2, param3 - 1) } else { return 0 } } ! doMyStuff(true, true, 4)
  12. 12. Naming conventions • The importance of naming. What does this code do? ! func summation(fromNumber:Int, includeEven: Bool = true, includeOdd: Bool = true) -> Int { if fromNumber > 0 { var currentSum = 0 if fromNumber % 2 == 0 && includeOdd { currentSum = fromNumber } else if fromNumber % 2 == 1 && includeEven { currentSum = fromNumber } return currentSum + summation(fromNumber - 1, includeEven: includeEven, includeOdd: includeOdd) } else { return 0 } } ! summation(4)
  13. 13. Naming conventions • Names should be explicit and clear temp.active = YES; product.active = YES; ! ! • Provide context inactiveProducts.count; ! ! • Avoid shortcuts ! • Avoid Business/Technical names when possible ! • Follow language conventions (ivars, setters/getters, casing,…) ! • Be consistent (remove/delete, create/insert,…)
  14. 14. Code comments “Now hiring now. Right now we are hiring now”
  15. 15. Code comments • Issues • Can be outdated (misleading) • Require language switch ! • Types • Redundant //Start reachability notifications [[Reachability reachabilityForInternetConnection] startNotifier]; ! ! • Separate blocks with different responsibilities - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)index { //Create cell UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellIdentifier]; … //Configure cell … return cell; } ! • Commented-out code
  16. 16. Code comments • Code is not self-explanatory • Code has side effects //Careful! setting delegate reloads table content self.tableView.delegate = self; ! • Domain specific (complex math, business rules,…) • Public APIs in libs /** Loads Purchase history and returns MOReceipts @param block Block executed when the history is loaded. Contains parsed MOReceipts @param errorBlock Block executed when an error occurs */ - (void)updateReceiptsOnSuccess:(MOResponseArrayBlock)block error: (MOErrorBlock)errorBlock; ! • In general, avoid comments
  17. 17. Control sentences Where the linear flow ends
  18. 18. Control sentences • Format • Conditionals: • Simple expressions —> variables if (price - price * discountPercentage + discountAmount < minimumPrice) { println("Difficult clause") } ! let amountToPay = price - price * discountPercentage + discountAmount if (amountToPay < minimumPrice) {} ! • Do not use more than 3 or 4 expressions • Prefer positive clauses var notForbidden = false if !notForbidden {} ! ! • Do not use assignments or side effects if ((x = y * 2) != 0) {} if (self = [super init]) {} if (condition && [self destroyObject]) {}
  19. 19. Control sentences • Avoid Spaghetti code (nested depth < 3) if (condition1) { if (condition2) { for(i = 0; i < 10; i++) { if (condition4) { if (condition5) { } return; } } } } ! ! • Collapse when possible if (condition1) { if (condition2) { } } ! if (condition1 && condition2) { } ! • Do not use goto, break, continue
  20. 20. Control sentences • “if”statements • Avoid empty cases • Avoid obvious“else if”clauses if flag { } else if !flag { println("Difficult to read") } • “for”loops • Do not abuse for (;condition;) { /*...*/ } • Do not modify the conditional variable inside for (i = 0; i < 10; i++) { i *= 2; } ! • Ternary operators • Only use for assignments condition? [self method1] : [self method2]; name = user.name? : @"Anonymous"; ! • Must be extremely simple
  21. 21. Functions and methods Your code in small steps
  22. 22. Functions and methods • Clear naming summation(4) ! • 1 Level of abstraction let dates = downloadAndParse(“http://myrurl.com”) ! • Single Responsibility Principle (SRP) “Every context should have a single responsibility, and that responsibility should be entirely encapsulated by the context” - Wikipedia ! • No side effects ! • Explicit error handling - (BOOL)writeToURL:(NSURL *)aURL options:(NSDataWritingOptions)mask error:(NSError **)errorPtr;
  23. 23. Functions and methods • Parameters • Prefer over instance variables (or globals/statics) • Avoid output • Reduce amount (<4) [NSLayoutConstraint constraintWithItem:view1 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:view2 attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0.0] ! • 1 point of exit ! • Remove empty methods or only calling super ! - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { } return self; }
  24. 24. Classes Your building blocks
  25. 25. Classes • SRP. Check yourself: • Name should describe responsibility • Describe functionality without “and”,“or”,“but”,“if” • Do you have flags? ! • Open-Close principle “Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification” - Wikipedia ! • Hide all implementation details • Simplify public headers/methods/properties ! • Explicit dependencies ! • Sort you methods and properties (public/private)
  26. 26. Classes • Avoid statics ! • Use polymorphism if (a.isKindOfClass(MyClass)) { ! ! • Take advantage of categories MyProjectUtils.convertToUrlEncoding("hello") StringUtils.convertToUrlEncoding(“hello") “hello".convertToUrlEncoding() ! "hello".drawInRect(rect:rect, withAttributes: attributes) ! • Sort your toolbox!
  27. 27. Modules Integrating all the pieces
  28. 28. Modules • SoC “Design principle for separating a computer program into distinct sections, such that each section addresses a separate concern. A concern is a set of information that affects the code of a computer program”. Wikipedia ! • Explicit • API • Callbacks (protocols, blocks,…) • Threads ! • Split by functionality vs type ! • Hide internals ! • Structure your data - (NSDictionary *)findNearestPersonToLocation:(NSArray *)coordinates; - (Person *)findNearestPersonToLocation:(CLLocationCoordinate2D)coordinate;
  29. 29. Modules • Dependencies • Law of Demeter “LoD can be succinctly summarized in one of the following ways: • Each unit should have only limited knowledge about other units: only units "closely" related to the current unit. • Each unit should only talk to its friends; don't talk to strangers. • Only talk to your immediate friends.”. Wikipedia ! aVar.getB().getC() ! ! • Avoid cycles ! • Prefer Interfaces vs concrete classes ! • Isolate lifecycle ! • Make proper use of Software patterns A B C
  30. 30. Software patterns Everybody can ride a bike
  31. 31. Software patterns • Robust, flexible and well known solutions ! • Reduce cognitive load “Among psychologists it is widely acknowledged that, compared to "cold" learning, people learn more effectively when they can build on what they already understand”. Wikipedia. ! • Some of most interesting: • MVC / MVVM • Inheritance / Composition • Inversion Of Control / Dependency Injection • Delegate/Observer • Factory • Chain Of Responsibility • ….
  32. 32. MVC • Model • Contains information in Plain objects • Connects to endpoints, DB,.… • View • Draws the screen • Receives/passes events to/from controllers • Controller • Connects the View and the Model layers ! • Most common pitfalls in iOS • Massive controllers (DataSources, components,…) • Controllers doing Model/View work • View & Controller coupling ! • Alternative: MVVM (Model-View-ViewModel)
  33. 33. Inheritance vs Composition • Inheritance is good for“is-a”relations • Use composition as default Inheritance Composition Difficult to keep SRP Easy to keep SRP Details from base class to subclasses Close components Massive base classes Small components Behaviour on compilation time Behaviour on runtime
  34. 34. Inversion of Control / Dependency Injection • Increase reusability of modules • Lifecycle controlled on system level • IoC • Invert relation code-3rd party • Generic API definitions • Dependencies are provided • DI • Dependencies are injected (constructors, setters) ! class TextEditor { var checker = SpellCheckerES() //TextEditor coupled with ES checker } ! class TextEditor { var checker: SpellChecker init(checker: SpellChecker) { self.checker = checker //Implementation of checker decided by DI controller } }
  35. 35. Programming paradigms Learning from others
  36. 36. Aspect Oriented Programming • Ideal for cross-cutting concerns ! • Hooks code before/after methods ! • Aspects (https://github.com/steipete/Aspects) [UIViewController aspect_hookSelector:@selector(viewWillAppear:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> aspectInfo, BOOL animated) { NSLog(@"View Controller will appear"); } error:nil];
  37. 37. Reactive programming • Ideal for event-driven datasources ! • Automatic propagation of changes ! • Reduces/hides state • Time independent code ! • Reactive Cocoa (https://github.com/ReactiveCocoa/ReactiveCocoa) RAC(self.logInButton, enabled) = [RACSignal combineLatest:@[ self.usernameTextField.rac_textSignal, self.passwordTextField.rac_textSignal, RACObserve(LoginManager.sharedManager, loggingIn) ] reduce:^(NSString *username, NSString *password, NSNumber *loggingIn) { return @(username.length > 0 && password.length > 0 && !loggingIn.boolValue); }];
  38. 38. Functional programming • Mimic mathematical functions ! • Avoids state ! • Outputs only dependent on inputs • No side effects • Parallelizable • Predictable (race conditions) ! • Chainable operations ! let evenSum = Array(1...10) .filter { (number) in number % 2 == 0 } .reduce(0) { (total, number) in total + number }
  39. 39. Tools Computers can also help you
  40. 40. Tools • Uncrustify (http://uncrustify.sourceforge.net/) ! • OCLint (http://oclint.org/) ! • Sonar for Objective-C (https://github.com/octo-technology) ! • Objc-dependency-visualizer (https://github.com/PaulTaykalo/objc-dependency-visualizer)
  41. 41. References • Clean code: A handbook of Agile Software Craftsmanship ! ! ! ! ! ! ! ! ! ! • Objc.io (http://www.objc.io/)
  42. 42. Thank you! Q&A

×