Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Software Design & Eclecticism

Software Design & Eclecticism

What makes Foundation stand out among other standard libraries is how thoroughly it's designed. From its date and time calculations to its internationalization and URL loading system, Cocoa APIs demonstrate thoughtfulness and a deep appreciation for understanding a problem in its entirety.

In the service of cultivating a sense and appreciation of good software design, this session will explore a variety of topics, including beer taxonomy, international shoe sizes, NFPA 704 "fire diamonds", and the French Republican Calendar, applying patterns and conventions in Objective-C and Cocoa to model these obscure subjects.

In the service of cultivating a sense and appreciation of good software design, this session will explore a variety of topics, including beer taxonomy, SMPTE film timecodes, international shoe sizes, NFPA 704 "fire diamonds", and the French Republican Calendar, applying patterns and conventions in Objective-C and Cocoa to model these obscure subjects.

Mattt Thompson

March 24, 2014
Tweet

More Decks by Mattt Thompson

Other Decks in Programming

Transcript

  1. Software
    Design &
    Eclecticism

    View Slide

  2. • UITableView Wrangler
    • URL Request Slinger
    • JSON Serialization Expert
    • Getter/Setter Go-Getter
    • Documentation Force of Nature
    • NSManagedObject Whisperer

    View Slide

  3. This is a talk about getting back to what 

    I love most about programming

    View Slide

  4. French Republican Calendar

    View Slide

  5. 1793 – 1805

    View Slide

  6. Design Goals

    View Slide

  7. 12 Months of
    3 Weeks of
    10 Days of
    10 Hours of
    100 Minutes of
    100 Seconds

    View Slide

  8. Vendémiaire Nivôse Germinal Messidor
    Brumaire Pluviôse Floréal Thermidor
    Frimaire Ventôse Prairial Fructidor
    -aire -ôse -al -dor

    View Slide

  9. 1.primidi
    2.duodi
    3.tridi
    4.quartidi
    5.quintidi

    6.sextidi
    7.septidi
    8.octidi
    9.nonidi
    10.décadi

    View Slide

  10. Brumaire 1
    Pomme
    Pluviôse 25
    Lièvre

    View Slide

  11. 360 Days
    + 

    5 or 6 

    “Complementary Days”

    View Slide

  12. Les Jours Complémentaires
    • Celebration of Virtue
    • Celebration of Talent
    • Celebration of Labor
    • Celebration of Convictions
    • Celebration of Honors
    • Celebration of the Revolution

    View Slide

  13. NSCalendar

    View Slide

  14. NSCalendar 

    -initWithCalendarIdentifier:

    View Slide

  15. • Gregorian
    • Buddhist
    • Chinese
    • Hebrew
    • Islamic
    • Islamic Civil

    • Japanese
    • Republic of China
    • Persian
    • Indian
    • ISO 8601

    View Slide

  16. _NSCopyOnWriteCalendarWrapper


    CFCalendarRef

    View Slide

  17. @interface _FRARepublicanCalendar : 

    NSCalendar
    @end

    View Slide

  18. NSString * const 

    NSCalendarIdentifierFrenchRepublican =

    @"calendrier-républicain-français"

    View Slide

  19. - (id)fra_initWithCalendarIdentifier:(NSString *)ident 

    __attribute__((objc_method_family(init))) 

    {
    if ([ident isEqualToString:
    NSCalendarIdentifierFrenchRepublican]) {
    return [[_FRARepublicanCalendar alloc] init];
    }
    !
    return [self fra_initWithCalendarIdentifier:ident];
    }

    View Slide

  20. - (NSRange)maximumRangeOfUnit:(NSCalendarUnit)unit {
    switch (unit) {
    case NSYearCalendarUnit:
    return NSMakeRange(-NSUIntegerMax, NSUIntegerMax);
    case NSMonthCalendarUnit: return NSMakeRange(1, 13);
    case NSWeekCalendarUnit: return NSMakeRange(1, 3);
    case NSWeekdayCalendarUnit: return NSMakeRange(1, 10);
    case NSDayCalendarUnit: return NSMakeRange(1, 30);
    case NSHourCalendarUnit: return NSMakeRange(1, 10);
    case NSMinuteCalendarUnit: return NSMakeRange(1, 100);
    case NSSecondCalendarUnit: return NSMakeRange(1, 100);
    case NSEraCalendarUnit:
    default: return NSMakeRange(0, 0);
    }
    }

    View Slide

  21. NSTimeInterval const
    FRAFrenchRevolutionaryEpoch =
    2375839.5; // 22 September 1792

    View Slide

  22. - components:

    fromDate:
    - dateByAddingComponents:

    toDate:
    - dateFromComponents:

    View Slide

  23. Phone Numbers

    View Slide

  24. +1 (555) 555 - 1234
    United States

    View Slide

  25. +44 20 1234 5678
    United Kingdom

    View Slide

  26. 1 2
    ABC
    3
    DEF
    4
    GHI
    5
    JKL
    6
    MNO
    7
    PQRS
    8
    TUV
    9
    WXYZ
    ˎ 0
    +
    #

    View Slide

  27. Whitby 

    01947 (WH)

    View Slide

  28. 1-800-HIPSTER
    Alphabetical Phone Number

    View Slide

  29. +1 (555) 555 - 6789 x42
    Extension

    View Slide

  30. 911
    Emergency Number

    View Slide

  31. 55422
    SMS Short Code

    View Slide

  32. IP Addresses

    View Slide

  33. E.164
    Telephone Numbering Plan

    View Slide

  34. International Access Code 011
    Country Code +44
    Area Code 555
    Subscriber Number 555 1234
    Extension x42

    View Slide

  35. E164PhoneNumberComponents

    View Slide

  36. • @property NSString *internationalAccessCode
    • @property NSString *countryCode
    • @property NSString *areaCode
    • @property NSString *subscriberNumber
    • @property NSString *extension
    • @property NSString *emergencyNumber
    • @property NSString *shortCode

    View Slide

  37. E164PhoneNumberComponents

    View Slide

  38. E164PhoneNumberFormatter
    • @property NSLocale *locale
    • @property NSString *countryCodePrefix
    • @property NSString *extensionPrefix

    View Slide

  39. - phoneNumberWithComponents:
    - components:

    fromPhoneNumber:

    View Slide

  40. NFPA 704 

    Hazard Identification System

    View Slide

  41. 3
    2 0
    Ethyl Alcohol
    CH3CH2OH

    View Slide

  42. 1
    0 2
    Sodium Hydride
    NaH
    W

    View Slide

  43. 4
    3 2
    W

    View Slide

  44. 4
    3 2
    W
    • @property flammabilityLabel
    • @property healthLabel
    • @property reactivityLabel
    • @property specialNoteLabel

    View Slide

  45. 4
    3 2
    W
    • @property flammabilityBackgroundColor
    • @property healthBackgroundColor
    • @property reactivityBackgroundColor
    • @property specialNoteBackgroundColor

    View Slide

  46. typedef NS_ENUM(NSUInteger, NFPA704HazardLevel) {
    NFPA704MinimalHazard = 0,
    NFPA704SlightHazard = 1,
    NFPA704ModerateHazard = 2,
    NFPA704SeriousHazard = 3,
    NFPA704ExtremeHazard = 4,
    };
    • @property NFPA704HazardLevel flammability
    • @property NFPA704HazardLevel health
    • @property NFPA704HazardLevel reactivity
    • @property NSString *specialNote

    View Slide

  47. CGContextSaveGState(ctx);
    {
    CGContextTranslateCTM(ctx,CGRectGetWidth(rect)/2.0f, 0.0f);
    CGContextRotateCTM(ctx, M_PI_4);
    CGContextScaleCTM(ctx, 1.0f / M_SQRT2, 1.0f / M_SQRT2);
    // …
    }
    CGContextRestoreGState(ctx);

    View Slide

  48. Beer Measurement

    View Slide

  49. @interface Beer
    @property NSString *name
    @property id brewery
    @property NSNumber *ABV
    @property NSNumber *IBU
    @property NSNumber *SRM

    View Slide

  50. °L Example Color EBC
    2 Pale lager, Witbier, Pilsener, Berliner Weisse 4
    3 Maibock, Blonde Ale 6
    4 Weissbier 8
    6 American Pale Ale, India Pale Ale 12
    8 Weissbier, Saison 16
    10 English Bitter, ESB 20
    13 Biere de Garde, Double IPA 26
    17 Dark lager, Vienna lager, Marzen, Amber Ale 33
    20 Brown Ale, Bock, Dunkel, Dunkelweizen 39
    24 Irish Dry Stout, Doppelbock, Porter 47
    29 Stout 57
    35 Foreign Stout, Baltic Porter 69
    40+ Imperial Stout 79

    View Slide

  51. Morey Equation
    MCU =
    weight of grains (lbs) • color of grains (°L)
    volume (gallons)
    SRM = 1.4922 • MCU^0.6859

    View Slide

  52. Morey Approximation
    UIColor * UIColorForDegreesLovibond(CGFloat lovibond) {
    CGFloat r, g, b;
    if (lovibond < 1.7f) {
    r = 226.6017f, g = 174.7456f, b = 101.7924;
    } else if (lovibond > 600.0f) {
    r = 76.52f, g = 58.344f, b = 47.936f;
    } else {
    r = (227.3 - 0.4112 * lovibond) + (0.0002665 * powf(lovibond, 2.0f));
    g = (175.5 - 0.4445 * lovibond) + (0.0004154 * powf(lovibond, 2.0f));
    b = (102.2 - 0.2402 * lovibond) + (0.0002496 * powf(lovibond, 2.0f));
    }
    !
    return [UIColor colorWithRed:(r / 255.0f)
    green:(g / 255.0f)
    blue:(b / 255.0f) alpha:1.0f];
    }

    View Slide

  53. @interface BeerView
    - setBeer:

    View Slide

  54. Shoe Sizing

    View Slide

  55. UK Barleycorn ⅓ inch
    France Paris Point ⅔ cm

    View Slide

  56. • Europe
    • UK
    • Australia
    • USA / Canada
    • Mexico
    • Japan
    • Korea

    • Inches
    • Centimeters
    Regional Systems Measurements

    View Slide

  57. ISO 9407
    Mondopoint

    View Slide

  58. 200 205 210 215 220 225 230 235 240 245 250 255 260 265 270 275 280 285 290 295 300 305 310 315 320
    7¾ 8 8¼ 8½ 8¾ 9 9¼ 9½ 9¾ 10 10¼ 10½ 10¾ 11 11¼ 11½ 11¾ 12 12¼ 12½
    [mm]
    [in]
    foot
    215 220 225 230 235 240 245 250 255 260 265 270 275 280 285 290 295 300 305 310 315 320 325 330 335
    8¼ 8½ 8¾ 9 9¼ 9½ 9¾ 10 10¼ 10½ 10¾ 11 11¼ 11½ 11¾ 12 12¼ 12½ 12¾ 13
    [mm]
    [in]
    shoe
    Mondopoint 200 205 210 215 220 225 230 235 240 245 250 255 260 265 270 275 280 285 290 295 300 305 310 315 320
    EUR 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
    UK 0 0½ 1 1½ 2 2½ 3 3½ 4 4½ 5 5½ 6 6½ 7 7½ 8 8½ 9 9½ 10 10½ 11 11½ 12 12½ 13 13½ 14
    64ø. 1 1½ 2 2½ 3 3½ 4 4½ 5 5½ 6 6½ 7 7½ 8 8½ 9 9½ 10 10½ 11 11½ 12 12½ 13 13½ 14 14½ 15
    64ø.ø "UIM
    2 2½ 3 3½ 4 4½ 5 5½ 6 6½ 7 7½ 8 8½ 9 9½ 10 10½ 11 11½ 12 12½ 13 13½ 14
    64ø8ø '*"
    2 2½ 3 3½ 4 4½ 5 5½ 6 6½ 7 7½ 8 8½ 9 9½ 10 10½ 11 11½ 12 12½ 13 13½ 14 14½ 15 15½ 16
    64ø8ø "UIM
    3 3½ 4 4½ 5 5½ 6 6½ 7 7½ 8 8½ 9 9½ 10 10½ 11 11½ 12 12½ 13 13½ 14 14½ 15
    JP/CN 20 20½ 21 21½ 22 22½ 23 23½ 24 24½ 25 25½ 26 26½ 27 27½ 28 28½ 29 29½ 30

    View Slide

  59. Function or Lookup Table?

    View Slide

  60. #import
    !
    extern double USAWomensSizeToMondopoint(double size);
    !
    - (void)testUSAWomensSizeToMondopointEquivalences {
    static NSDictionary *mondopointByWomensSize =
    @{@(2): @(203), ...};
    !
    [mondopointByWomensSize enumerateKeysAndObjectsUsingBlock:
    ^(NSNumber *womensSize, NSNumber *mondopoint, BOOL *stop) {
    XCTAssertEqual(
    USAWomensSizeToMondopoint([womensSize doubleValue]),
    [mondopoint doubleValue],
    @"sizes not equivalent”
    );
    }];
    }

    View Slide

  61. Braille

    View Slide

  62. a/1 b/2 c/3 d/4 e/5 f/6 g/7 h/8 i/9 j/0
    k l m n o p q r s t
    u v x y z w

    View Slide

  63. Comma Semicolon Apostrophe Colon Hyphen Decimal point
    Full stop!
    (Period)
    Exclamation!
    point
    Open quote,!
    question mark
    Close!
    quote
    Bracket!
    (Parentheses)
    Slash!
    (Fraction)

    View Slide

  64. UISimpleTextPrintFormatter

    View Slide

  65. NSMutableString *mutableText = [text mutableCopy];
    !
    CFStringTransform(mutableText, NULL,
    kCFStringTransformToLatin, NO);
    !
    CFStringTransform(mutableText, NULL,
    kCFStringTransformStripCombiningMarks, NO);
    !
    text = [NSString stringWithString:mutableText];

    View Slide

  66. NSMutableString *mutableBrailleText = [NSMutableString string];
    [text enumerateSubstringsInRange:NSMakeRange(0, [text length])
    options:NSStringEnumerationByComposedCharacterSequences
    usingBlock:
    ^(NSString *substring, …) {
    [mutableBrailleText appendString:
    EnglishBrailleCharacterForCharacter([substring characterAtIndex:0])];
    }];
    !
    [super setText:mutableBrailleText];

    View Slide

  67. static NSString * EnglishBrailleCharacterForCharacter(unichar character) {
    switch (character) {
    case 'a':
    return @"⠁";
    case 'b':
    return @"⠃";
    // ...
    }
    !
    return nil;
    }

    View Slide

  68. Concepts
    • Swizzling & Private Class Clusters
    • Formatters vs. Value Transformers vs. Functions
    • View Composition & Transformations
    • Model-Driven Views
    • Unit Conversion Strategies & Unit Testing
    • String Enumeration & UIPrinterFormatter

    View Slide