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

Anti-Patterns

Rob Brown
September 13, 2012

 Anti-Patterns

Sometimes to better know the right way to do things we have to first look at the wrong way.

Rob Brown

September 13, 2012
Tweet

More Decks by Rob Brown

Other Decks in Programming

Transcript

  1. Ask Questions My best presentations are not from what I

    say but rather what you ask It’s also fine not to agree with me
  2. What is an anti-pattern? James Dempsey: Good intentions gone awry

    Code and practices you should avoid The code you write when you are writing it wrong
  3. Principles to Remember Form good habits Optimize to humans Learn

    the rules well so you know when and how to break them.
  4. Magic Numbers Magic numbers are evil They don’t convey any

    context They are like numbers with out units
  5. #define #define is a simple copy-and-paste operation with no sense

    of context There are lots of gotchas Rule of thumb: If #if isn’t involved, don’t use #define
  6. #define #define MAX(A, B) ((A) > (B) ? (A) :

    (B)) int x = 1; int y = 2; MAX(++x, ++y) = ?
  7. #define Proper constants: const NSUInteger kTheAnswer = 42u; NSString *

    const kGreeting = @”Hello World!”; In header file: extern const NSUInteger kTheAnswer; extern NSString * const kGreeting;
  8. Mass Constant Files Constant files make code less reusable Constants

    should be as close possible to their relevant code Categories are often a good place for constants
  9. Implicit Type Conversions Operations must be performed on the same

    primitive types Type conversions may not be what you expect
  10. Implicit Type Conversions Common mistakes: (-1 < 0u) => False

    (1 / 2) => 0 for (uint32 i = 10; i >= 0; i--) { } => Infinite loop
  11. Implicit Type Conversions Rules: Signed int to larger signed int

    The smaller value is sign-extended Signed int to same-sized unsigned int Bit pattern preserved
  12. Implicit Type Conversions Rules: Signed int to larger unsigned int

    Sign-extended then interpreted as unsigned Signed int to larger unsigned int Zero-extended
  13. Implicit Type Conversions Rules: Unsigned int to same-sized int Interpreted

    as signed, may become negative Unsigned into to larger-sized int Zero-extended, then interpreted as signed
  14. Implicit Type Conversions int: 42 unsigned int: 2u long: 3l

    unsigned long: 5ul long long 10ll unsigned long long 100ull float: 2.0f double: 3.14
  15. Bit Fields enum { BitFieldNone = 0ull, BitFieldOne = 1ull,

    BitFieldTwo = 2ull, ... BitFieldThirtyThree = 8589934592ull, BitFieldAll = 18446744073709551615ull, }; typedef UInt64 BitField;
  16. Bit Fields enum { BitFieldNone = 0ull, BitFieldOne = 1ull

    << 0, BitFieldTwo = 1ull << 1, ... BitFieldThirtyThree = 1ull << 32, BitFieldAll = ~BitFieldNone, }; typedef UInt64 BitField;
  17. Unenforced Assumptions If you ever make an assumption, assert it

    If the assertion fails, you immediately know either your code or your assumption is wrong Assertions help catch bugs closer to the source Assumptions should also be documented
  18. Unenforced Assumptions NSParameterAssert(number > 0 && number < 100); NSCParameterAssert([string

    length] > 0u); NSAssert([NSThread isMainThread], @”Oops”); NSCAssert(value != nil, @”Oops”);
  19. Overly Intimate Code Outside classes should only know what they

    need Encapsulation is one of the key principles of OOP Class extensions are great for private methods/data Categories are great for protected methods/data
  20. Dead Code Dead code is just clutter Increases compile time

    Even though the code is no longer used, it still has mental maintenance costs Massive commented out methods are just as bad
  21. Instance Variables Instance variables should not be accessed directly Getters

    and setters should be used instead Essentially internal encapsulation
  22. Instance Variables Benefits of accessors: Enforce constraints Protect data integrity

    Provide flexibility Only minimal efficiency loss KVO Accessors don’t need to be backed by an ivar
  23. Branching on Classes Branching on classes is essentially reimplementing polymorphism

    Categories solve this problem Not all languages support categories
  24. Branching on Classes // Bad example if ([asset isKindOfClass:[Video class]])

    [asset processVideo]; else if ([asset isKindOfClass:[Photo class]]) [asset processPhoto];
  25. Branching on Classes // Categories @implementation Video (Processing) - (void)processAsset

    { } @end @implementation Photo (Processing) - (void)processAsset { } @end
  26. Oversized Methods Short methods are easier to read and reuse

    Rule of thumb: 1-20 lines is optimal 100+ lines is excessive
  27. Long Lines Shorter lines are easier to read Not everyone

    has 27+ inch screens Xcode doesn’t auto-wrap text very well Rule of thumb: 80-100 characters per line
  28. Whitespace Whitespace makes code more readable It separates parts of

    methods into natural sections These sections are best accompanied with comments
  29. Name Spacing Often classes have the same name Example: User,

    Tweet, Photo Naming conflicts are painful to fix
  30. Name Spacing Some languages, such as C++, include name spaces

    The convention in Objective-C is to use 2-3 character prefixes
  31. Want to Learn More? Code Complete 24 Deadly Sins of

    Software Security http://www.cprogramming.com/tutorial/ cpreprocessor.html