|
| 1 | +# Rails Patterns & AntiPatterns |
| 2 | + |
| 3 | +I just want to build software like a pro. |
| 4 | + |
| 5 | + |
| 6 | + |
| 7 | +### Topics |
| 8 | + |
| 9 | +* [Law of Demeter](#law-of-demeter) |
| 10 | +* [ActiveRecord](#activerecord) |
| 11 | +* [Presenters](#presenters) |
| 12 | +* [Single Responsibility Principle](#single-responsibility-principle) |
| 13 | +* [Null Object Pattern](#null-object-pattern) |
| 14 | +* [Factory](#factory) |
| 15 | +* [Facade](#facade) |
| 16 | +* [Fat Models, Skinny Controllers](#fat-models-skinny-controllers) |
| 17 | +* [CodeRetreat](#coderetreat) |
| 18 | + |
| 19 | +-- |
| 20 | + |
| 21 | +### Law of Demeter |
| 22 | + |
| 23 | +The Law of Demeter (LoD) or principle of least knowledge is a design guideline for developing software, particularly object-oriented programs. In its general form, the LoD is a specific case of loose coupling. The guideline was proposed at Northeastern University towards the end of 1987, and can be succinctly summarized in each of the following ways:[1] |
| 24 | + |
| 25 | +* Each unit should have only limited knowledge about other units: only units "closely" related to the current unit. |
| 26 | +* Each unit should only talk to its friends; don't talk to strangers. |
| 27 | +* Only talk to your immediate friends. |
| 28 | + |
| 29 | +The fundamental notion is that a given object should assume as little as possible about the structure or properties of anything else (including its subcomponents), in accordance with the principle of "information hiding". |
| 30 | + |
| 31 | +#### Problem |
| 32 | + |
| 33 | +```ruby |
| 34 | +class Article < ActiveRecord::Base |
| 35 | + belongs_to :author |
| 36 | +end |
| 37 | + |
| 38 | +class Author < ActiveRecord::Base |
| 39 | + has_many :articles |
| 40 | + has_one :personal_information |
| 41 | +end |
| 42 | + |
| 43 | +class PersonalInformation < ActiveRecord::Base |
| 44 | + belongs_to :author |
| 45 | +end |
| 46 | + |
| 47 | +=> article.author.personal_information.name |
| 48 | +=> article.author.personal_information.birthdate |
| 49 | +=> article.author.personal_information.gender |
| 50 | +=> article.author.personal_information.city |
| 51 | +=> article.author.personal_information.last_name |
| 52 | +``` |
| 53 | + |
| 54 | +#### Solution |
| 55 | + |
| 56 | +```ruby |
| 57 | +class Author < ActiveRecord::Base |
| 58 | + has_many :articles |
| 59 | + has_one :personal_information |
| 60 | + |
| 61 | + def name |
| 62 | + personal_information.name |
| 63 | + end |
| 64 | + |
| 65 | + def birthdate |
| 66 | + personal_information.birthdate |
| 67 | + end |
| 68 | + |
| 69 | + def gender |
| 70 | + personal_information.gender |
| 71 | + end |
| 72 | + |
| 73 | + def city |
| 74 | + personal_information.city |
| 75 | + end |
| 76 | + |
| 77 | + def last_name |
| 78 | + personal_information.last_name |
| 79 | + end |
| 80 | +end |
| 81 | + |
| 82 | +class Article < ActiveRecord::Base |
| 83 | + belongs_to :author |
| 84 | + |
| 85 | + def author_name |
| 86 | + personal_information.name |
| 87 | + end |
| 88 | + |
| 89 | + def author_birthdate |
| 90 | + personal_information.birthdate |
| 91 | + end |
| 92 | + |
| 93 | + def author_gender |
| 94 | + personal_information.gender |
| 95 | + end |
| 96 | + |
| 97 | + def author_city |
| 98 | + personal_information.city |
| 99 | + end |
| 100 | + |
| 101 | + def author_last_name |
| 102 | + personal_information.last_name |
| 103 | + end |
| 104 | +end |
| 105 | +``` |
| 106 | + |
| 107 | +#### +2 Solution |
| 108 | + |
| 109 | +```ruby |
| 110 | +class Author < ActiveRecord::Base |
| 111 | + has_many :articles |
| 112 | + has_one :personal_information |
| 113 | + |
| 114 | + delegate :name, |
| 115 | + :birthdate, |
| 116 | + :gender, |
| 117 | + :city, |
| 118 | + :last_name, |
| 119 | + to: :personal_information |
| 120 | +end |
| 121 | + |
| 122 | +class Article < ActiveRecord::Base |
| 123 | + belongs_to :author |
| 124 | + |
| 125 | + delegate :name, |
| 126 | + :birthdate, |
| 127 | + :gender, |
| 128 | + :city, |
| 129 | + :last_name, |
| 130 | + to: :author, |
| 131 | + prefix: true |
| 132 | + |
| 133 | +end |
| 134 | +``` |
| 135 | + |
| 136 | +### ActiveRecord |
| 137 | + |
| 138 | +In software engineering, the active record pattern is an architectural pattern found in software that stores in-memory object data in relational databases. It was named by Martin Fowler in his 2003 book Patterns of Enterprise Application Architecture.[1] The interface of an object conforming to this pattern would include functions such as Insert, Update, and Delete, plus properties that correspond more or less directly to the columns in the underlying database table. |
| 139 | + |
| 140 | +The active record pattern is an approach to accessing data in a database. A database table or view is wrapped into a class. Thus, an object instance is tied to a single row in the table. After creation of an object, a new row is added to the table upon save. Any object loaded gets its information from the database. When an object is updated the corresponding row in the table is also updated. The wrapper class implements accessor methods or properties for each column in the table or view. |
| 141 | + |
| 142 | +#### Example |
| 143 | + |
| 144 | +```ruby |
| 145 | +class User < ActiveRecord::Base |
| 146 | +end |
| 147 | +``` |
| 148 | + |
| 149 | +[Code](active_record) |
| 150 | + |
| 151 | +### Presenters |
| 152 | +Coming soon... |
| 153 | + |
| 154 | +### Single Responsibility Principle |
| 155 | +Coming soon... |
| 156 | + |
| 157 | +### Null Object Pattern |
| 158 | +Coming soon... |
| 159 | + |
| 160 | +### Factory |
| 161 | +Coming soon... |
| 162 | + |
| 163 | +### Facade |
| 164 | +Coming soon... |
| 165 | + |
| 166 | +### Fat Models, Skinny Controllers |
| 167 | +Coming soon... |
| 168 | + |
| 169 | +### CodeRetreat |
| 170 | +Coming soon... |
0 commit comments