{"id":389,"date":"2014-04-06T23:24:52","date_gmt":"2014-04-06T21:24:52","guid":{"rendered":"http:\/\/andras.palfi.hu\/?p=389"},"modified":"2014-04-06T23:24:52","modified_gmt":"2014-04-06T21:24:52","slug":"coding-guidelines","status":"publish","type":"post","link":"https:\/\/andras.palfi.hu\/?p=389","title":{"rendered":"Coding Guidelines"},"content":{"rendered":"<h2>General<\/h2>\n<p>The main reason of this document is to help to achieve a <b>clean<\/b> code, which is:<\/p>\n<ul>\n<li><b>Readable<\/b>: easily understandable &#8211; by other developers<\/li>\n<li><b>Maintainable: <\/b>easily changeable by other developers as well<\/li>\n<li><b>Flexible<\/b>: can be extended and add new functionality<\/li>\n<li><b>Testable<\/b>: can be unit testable \u2013 where other classes are mocked even if the classes are the part of the component or not. The test should cover at least a positive and a negative flow where the mock objects provide different results.<\/li>\n<\/ul>\n<h3>Design\/architecture<\/h3>\n<ul>\n<li><b>One file \u2013 one class<\/b>: it is very confusing if a file contains different classes. The project structure should mirror the class structure.<\/li>\n<li><b>One class &#8211; one responsibility<\/b>: each class has to have one specific concern. Do not create huge classes, which performs different tasks and stores different states.<\/li>\n<li>Keep the <b>class size<\/b> fewer than 600 lines. If the lines exceed the limit it probably means the class performs to many tasks and should separate to more classes.<\/li>\n<li><b>One method &#8211; one task<\/b>:<b> <\/b>one simple task should be performed by a method<b><\/b><\/li>\n<li>Keep the <b>method size<\/b> less than 60 lines or one screen size. Preferable is less. Much easier to overview a smaller method. Moving code to smaller methods makes the original method more readable, especially if you use descriptive names \u2013 and you should. The smaller methods are more reusable and maintainable as well and changing them can introduce fewer errors.<\/li>\n<li><b>Different modules <\/b>should not be referenced directly even if the module is part of the code or a third-party library. Direct references make harder (or impossible) the proper unit testing and also the possibility to vary the classes later. Declaring a clear <b>minimum<\/b>&#8211;<b>protocol<\/b> also helps the proper planning. If a module contains more classes the classes can depend on each other of course.<\/li>\n<li><b>Accessing different modules<\/b>: keep reference only to the objects you really have to.<\/li>\n<\/ul>\n<ol>\n<li>Use parameters: the most easier to test and provides the clearest architecture also the most understandable approach.<\/li>\n<li>Use properties to set the dependent instances.<\/li>\n<li>Use a public dedicated class (service locator), which provides the required instances (dedicated methods provide the instances of singletons or can behave like factories).<\/li>\n<li>Use singletons only if you\u2019re don\u2019t have any other option.<\/li>\n<\/ol>\n<h3>Naming<\/h3>\n<ul>\n<li><b>Use self-descriptive names<\/b>. The name should suggest <b>what<\/b> <b>the method does<\/b>. Good names can institute simple comments. Avoid shortenings. Always think of the mind of a developer who doesn\u2019t work on the project: will he\/she understand what is that method\/variable? What it does?<\/li>\n<li><strong>File names<\/strong> should be the same as the <strong>class names<\/strong>. Remember: one file, one class.<\/li>\n<\/ul>\n<h3>Coding<\/h3>\n<ul>\n<li>Keep the code <i>clean (apply the guideline)<\/i>: don\u2019t hesitate to change a code snippet when you change or add something if you see the result is not <i>clear<\/i>. Leaving small dirty code snippets results in an unmaintainable code.<\/li>\n<li><b>Avoid code duplication<\/b>: if the same code snippet should be copied to somewhere else always make a new method instead and call that from both parts. The code will be more readable, understandable, maintainable and smaller.<\/li>\n<li><b>Separate queries<\/b> (getters) from <b>modifiers<\/b> (setters). Always be clear what a method does: modifies the state of the class or retrieves a value. Do not mix them!<\/li>\n<li>Do not use more than two (three) parameters for methods. If you really need more, consider passing a dedicated parameter object instead or use properties to set the desired values.<br \/>\nOther option is to change the logic of that part of the code as these kinds of problem suggest there is too much to do.<\/li>\n<li>Do not embed different method calls in each other. Limit it to one call for a parameter.<br \/>\nLong lines mean something is wrong with the code. Setting local variables and passing them to the call make the code much clearer and easier to debug.<\/li>\n<li><b>Do not use<\/b> string literals or constant number values in the code. Use named constants instead. The constant numbers do not say too much about the purpose of the values but their names can do. This way all the key constants will be in one place so the changes are simpler and the readers of the code also have an overview of the magic numbers in the code.\n<ul>\n<li>use const strings instead of string literals: helps debugging as well<\/li>\n<li>use enums, consts for constant numbers<\/li>\n<li>Do not call <b>long<\/b> running <b>operations<\/b> from main thread. They will block the main thread where the user interaction happen and the application will seems to unresponsive sluggish.<br \/>\n<b>Network <\/b>calls should run always on <b>background <\/b>thread.<\/li>\n<li>Do not use <b>exceptions<\/b> to signal simple errors (especially from init methods): exceptions are for critical and\/or developer errors. Return some default value (NULL\/nil) or provide a returning error parameter.<\/li>\n<li>Call property getter\/setter accessors instead of access ivars directly. One can modify later the getter\/setter to add additional logic or implement different behavior (for example lazy-binding, logging or debugging).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3>Comments<\/h3>\n<p>There are two types of comments regarding the target:<\/p>\n<ul>\n<li><b>Public comments <\/b>for the user who want to use the class: describe <b>what<\/b> the method does. Should be in the header file. Usually <i>doxygen<\/i> compatible comments should be used (for reference see: <a href=\"http:\/\/www.stack.nl\/~dimitri\/doxygen\/docblocks.html\">http:\/\/www.stack.nl\/~dimitri\/doxygen\/docblocks.html<\/a>)<\/li>\n<li><b>Private comments<\/b> for other developers who work on the code: describe <b>how<\/b> the method works. Always think you explain the code.<br \/>\nShould be in the implementation file and use regular commenting<\/li>\n<\/ul>\n<p>For comments keep in mind the following basic rules:<\/p>\n<ul>\n<li>Place a <b>file header<\/b> comment in each file; the structure and look should be declared by the project.<br \/>\nUsually the header contains the component\/class name, author, company and other general information<\/li>\n<li><b>Comment the class<\/b>: give a clear description about the main concern of the class. If necessary describe how the class should be used even with code snippets if necessary<\/li>\n<li><b>Comment each method\/property <\/b><\/li>\n<li>Use the single-line comment (\/\/) in the code instead of multiple line comments (\/* *\/).<\/li>\n<li>For readability reason add a space after the comment sign: <i>\/\/ a comment<\/i><\/li>\n<li>Do not add doxygen like comments <b>inside <\/b>methods \u2013 these won\u2019t be extracted and won\u2019t appear in the generated documentation!<\/li>\n<li><b>Do not leave commented code snippets in the code<\/b> in long term. If it really needed to let the code in, describe why was it commented out, when can one uncomment it.<br \/>\nCommented code blocks are meaningless and nobody knows after a time why that code was there or was commented out. Usually nobody will use that code part any more.<\/li>\n<\/ul>\n<h3>Spacing and Formatting<\/h3>\n<p>Can vary between projects but must be uniform in one project. Good practice to use the default formatting of the IDE\/language.<\/p>\n<p>&nbsp;<\/p>\n<h2>iOS<\/h2>\n<h3>General<\/h3>\n<p>Apple provides a clear documentation and guideline about coding: <a href=\"https:\/\/developer.apple.com\/library\/mac\/#documentation\/Cocoa\/Conceptual\/CodingGuidelines\/CodingGuidelines.html\">Coding Guidelines for Cocoa<\/a> at <a href=\"https:\/\/developer.apple.com\/library\/mac\/#documentation\/Cocoa\/Conceptual\/CodingGuidelines\/CodingGuidelines.html\">https:\/\/developer.apple.com\/library\/mac\/ &#8211; documentation\/Cocoa\/Conceptual\/CodingGuidelines\/CodingGuidelines.html<\/a>.<\/p>\n<p>As the apple guideline describes all aspects in a detailed way this document contains only the most frequent issues found in the existing code or where clarification was necessary.<\/p>\n<p>In some circumstances it is possible to avoid some of these rules but always discuss it with the team lead.<\/p>\n<h3>Naming<\/h3>\n<ul>\n<li>Usually unnecessary to explicitly declare iVars (instance variable, a member) for properties, the compiler automatically creates them for you. Using the latest XCode you don\u2019t have to specify the <i>@sythesize<\/i>s so the code will be more compact.<br \/>\nThe usage suggest you what is used: \u2018self.myIvar\u2019 a property, while an iVar (without the \u2018self.\u2019) would be \u2018myIvar\u2019 (@synthesize was used) or \u2018_myIvar\u2019 (@synthesize wasn\u2019t used).<br \/>\nIf you really need an ivar for a property there is usually also a reason to distinguish the ivar name with a prefix or postfix.<\/li>\n<li>Do not use <i>and<\/i> in method names for parameters, except if the method performs different actions (so the actions are delimited by the <i>and<\/i>, not the parameters):<br \/>\nwrong: &#8211; (int)runModalForDirectory:(NSString *)path andFile:(NSString*)name andTypes:(NSArray *)fileTypes;<br \/>\nbetter: &#8211; (int)runModalForDirectory:(NSString *)path file:(NSString *)name types:(NSArray *)fileTypes;<br \/>\ndifferent actions: &#8211; (BOOL)openFile:(NSString *)fullPath withApplication:(NSString *)appName andDeactivate:(BOOL)flag;<\/li>\n<li>Do not use <i>get<\/i> in getter accessor names.<\/li>\n<li>Class names and global shared constants should start with a short prefix, which is a unique abbreviation of the project or module, substituting namespaces what are missing in ObjC.<br \/>\nFor example: MAFLogonManager \u2013 Mobile Application Framework Logon Manager<\/li>\n<li>File names should be the same as the class name except in case of categories. Category file names should start with the original class name followed by a \u2018+\u2019 sign and the name of the category. For example: NSString (Additions) category should be in a file named NSString+Additions<\/li>\n<li>For singletons use the <i>shared<\/i> or <i>default<\/i> method name prefix for methods which provides the instance of the class<\/li>\n<li>For parameter (and local variable) names use a prefix: aParam, anObject, theObject.<br \/>\nThis marks that the variable is temporary. Useful further if the parameter would have the same name as an ivar or property.<\/li>\n<\/ul>\n<h3>Coding<\/h3>\n<ul>\n<li>There must be at least one <b>designated initializer<\/b>, which calls the designated initXXX method of the superclass. The designated initializer must be the method with the most parameters. Always override the original designated initializers when you make a new subclass (introducing a new of overriding an existing initializer) to make sure your initializers will run and your class will be initialized properly.<br \/>\nGood practice to call the designated initializer from other initializers in the same class.<\/li>\n<li>Set the <i>IBOutlet<\/i> <b>properties<\/b> to <i>nil<\/i> in <i>viewDidUnload<\/i> to release the resources. The XCode generates the code for you this way (for example if you add a new referencing outlet).<\/li>\n<li>Do not call accessors (setting to <i>nil<\/i> a property) from <i>dealloc <\/i>and always consider calling it from<i> init\u2026<\/i>. Call <i>release<\/i> in dealloc and set the <b>ivar<\/b> directly in init.<br \/>\nSubclasses can be already in invalid state (deallocated all iVars) when dealloc method of the <i>super<\/i> executes, making accessor methods potentially unreliable.<br \/>\nA setter method may be doing more things than simply releasing the property. It also sends out KVO notifications automatically even if you implement the setter\/getter manually. Even if you&#8217;re not implementing the setter yourself, a subclass might. In all cases it is not a good idea to run the related code from dealloc.<br \/>\nNote: XCode generates the code for you this way for example if you add a new referencing outlet through interface builder.<\/li>\n<li>Do not call <i>release<\/i> on the result of a property getter even if it was called on self.<\/li>\n<li>Put private <b>ivars<\/b> in the <b>implementation <\/b>file.<br \/>\nThe header file is published like a protocol. The user of the object doesn\u2019t have to know the inner structure of the class.<br \/>\n@implementation MyViewController {<br \/>\nint myIntIVar;<br \/>\n}<\/li>\n<li><b>Do not put<\/b> <b>private method<\/b> and <b>property declarations<\/b> into the public header file. It makes the class structure unnecessarily complex and dangerous if someone starts to use them. Put them into a class extension instead (the compiler doesn\u2019t force to declare private methods!).<br \/>\n@interface MyViewController ()<br \/>\n@property (nonatomic, copy) NSString *myPrivateProperty;<br \/>\n@end<\/li>\n<li>\u00a0Use the AppDelegate only for application level operations and events. Put other code to specific classes and ViewControllers. Keep the AppDelegate clean (refers to <i>one class-one concern<\/i>).<\/li>\n<\/ul>\n<h3>Common errors<\/h3>\n<ul>\n<li>Always consider the proper usage of property attributes.<br \/>\nA property to an <b>immutable<\/b> class can always get a <b>mutable<\/b> instance. Use <b><i>copy<\/i><\/b> (instead of <i>retain<\/i>) if you want to make sure the data won\u2019t change after the property was set. Mainly with strings and arrays.<\/li>\n<li>For button taps use <b>TouchUpInside<\/b> instead of touchDown or other touches except if that is the requirement.<\/li>\n<li>Don\u2019t forget to implement <b><i>viewDidUnload<\/i><\/b> if you have <i>viewDidLoad<\/i>.<br \/>\nIf there is a memory warning the system releases the hidden views and calls <i>viewDidUnload<\/i>. When the view will appear again the system loads the view again and calls <i>viewDidLoad<\/i>. Without a <i>viewDidUnLoad <\/i>the application will leak.<\/li>\n<li>Use the <b>dot notation<\/b> only for <b>properties<\/b>. Do not use them for parameterless methods.<\/li>\n<\/ul>\n<h3>Comments<\/h3>\n<ul>\n<li>Use <b><i>#pragma mark<\/i><\/b><i> <\/i>to visually partition code, and add a short, meaningful description to the given block<br \/>\n<i>#pragma mark \u2013 Public method implementations<\/i><\/li>\n<li>Use <b><i>!!!<\/i><\/b><i>, <b>???<\/b>, <b>TODO<\/b><\/i> or <b><i>FIXME<\/i><\/b><i> <\/i>in comments if you want to highlight something but don\u2019t let them in for a long period.<\/li>\n<li>In some cases you can use <b><i>#warning<\/i><\/b> or even <b><i>#error<\/i><\/b> in your code to signal special cases or avoid wrong usage of the code. Usually these are used in an <i>#if<\/i> or <i>#ifdef <\/i>condition.<\/li>\n<li>If the project uses other libraries always cross-references them even if there must be a project, which uses the precompiled libraries.<br \/>\nCross-referenced libraries are easier to debug and the development of the libraries are also easier.<\/li>\n<li>Using cross-referenced libraries all the <b>bundles<\/b> and used files should be <b>referenced<\/b> from the referenced projects (instead of using the built\/maven version).<br \/>\nModifying the file (for example an xml in the bundle of the referenced library) will be visible right after the modification. Otherwise the library should be submitted to the repository wait for the build and update the files using maven or other tool.<\/li>\n<\/ul>\n<h3>Project settings<\/h3>\n<ul>\n<li>If the project uses other libraries always cross-references them even if there must be a project, which uses the precompiled libraries.<br \/>\nCross-referenced libraries are easier to debug and the development of the libraries are also easier.<\/li>\n<li>Using cross-referenced libraries all the <b>bundles<\/b> and used files should be <b>referenced<\/b> from the referenced projects (instead of using the built\/maven version).<br \/>\n<span style=\"line-height: 1.5em;\">Modifying the file (for example an xml in the bundle of the referenced library) will be visible right after the modification. Otherwise the library should be submitted to the repository wait for the build and update the files using maven or other tool.<\/span><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>General The main reason of this document is to help to achieve a clean code, which is: Readable: easily understandable &#8211; by other developers Maintainable: easily changeable by other developers as well Flexible: can be extended and add new functionality Testable: can be unit testable \u2013 where other classes are mocked even if the classes [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"hide_page_title":"","footnotes":""},"categories":[19,3,8],"tags":[],"_links":{"self":[{"href":"https:\/\/andras.palfi.hu\/index.php?rest_route=\/wp\/v2\/posts\/389"}],"collection":[{"href":"https:\/\/andras.palfi.hu\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/andras.palfi.hu\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/andras.palfi.hu\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/andras.palfi.hu\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=389"}],"version-history":[{"count":0,"href":"https:\/\/andras.palfi.hu\/index.php?rest_route=\/wp\/v2\/posts\/389\/revisions"}],"wp:attachment":[{"href":"https:\/\/andras.palfi.hu\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=389"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/andras.palfi.hu\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=389"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/andras.palfi.hu\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=389"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}