Bài viết này mô tả quá trình tối ưu hóa behavior các đối tượng theo strategy pattern
Bạn đầu ta có class Gau với duy nhất 1 method hien_thi để show ra hình dáng của các con gấu
1 2 3 4 5 6 7 8 9 10 11 12 | <span class="token keyword">class</span> <span class="token class-name">Gau</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">hien_thi</span></span> p <span class="token string">"Hiển thị"</span> <span class="token keyword">end</span> <span class="token keyword">end</span> gau_truc <span class="token operator">=</span> <span class="token constant">Gau</span><span class="token punctuation">.</span><span class="token keyword">new</span> gau_truc<span class="token punctuation">.</span>hien_thi gau_do_choi <span class="token operator">=</span> <span class="token constant">Gau</span><span class="token punctuation">.</span><span class="token keyword">new</span> gau_do_choi<span class="token punctuation">.</span>hien_thi |
Do yêu cầu bài toán, ta thêm hành động “đi” cho các con gấu.
Cách 1
1 2 3 4 5 6 7 8 9 10 | <span class="token keyword">class</span> <span class="token class-name">Gau</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">di</span></span> p <span class="token string">"đi"</span> <span class="token keyword">end</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">hien_thi</span></span> p <span class="token string">"Hiển thị"</span> <span class="token keyword">end</span> <span class="token keyword">end</span> |
Nhưng do không phải gấu nào đi cũng giống nhau nên ta phải ghi đè ở các subclass
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <span class="token keyword">class</span> <span class="token class-name">GauTruc</span> <span class="token operator"><</span> <span class="token constant">Gau</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">di</span></span> p <span class="token string">"đi bằng chân"</span> <span class="token keyword">end</span> <span class="token keyword">end</span> <span class="token keyword">class</span> <span class="token class-name">GauDoChoi</span> <span class="token operator"><</span> <span class="token constant">Gau</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">di</span></span> p <span class="token string">"đi bằng động cơ"</span> <span class="token keyword">end</span> <span class="token keyword">end</span> <span class="token comment"># ...vân vân và mây mây</span> <span class="token keyword">class</span> <span class="token class-name">GauBong</span> <span class="token operator"><</span> <span class="token constant">Gau</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">di</span></span> p <span class="token string">"Không đi được"</span> <span class="token keyword">end</span> <span class="token keyword">end</span> gau_truc <span class="token operator">=</span> <span class="token constant">GauTruc</span><span class="token punctuation">.</span><span class="token keyword">new</span> gau_truc<span class="token punctuation">.</span>di gau_do_choi <span class="token operator">=</span> <span class="token constant">GauDoChoi</span><span class="token punctuation">.</span><span class="token keyword">new</span> gau_do_choi<span class="token punctuation">.</span>di gau_bong <span class="token operator">=</span> <span class="token constant">GauBong</span><span class="token punctuation">.</span><span class="token keyword">new</span> gau_bong<span class="token punctuation">.</span>di |
=> Các supclass kế thừa từ superclass “Gau” gây phức tạp, khó bảo trì và mở rộng sau này
Cách 2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | <span class="token keyword">class</span> <span class="token class-name">Gau</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">di</span></span> p <span class="token string">"đi"</span> <span class="token keyword">end</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">hien_thi</span></span> p <span class="token string">"Hiển thị"</span> <span class="token keyword">end</span> <span class="token keyword">end</span> <span class="token keyword">module</span> <span class="token constant">DiBangChan</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">di</span></span> p <span class="token string">"đi bằng chân"</span> <span class="token keyword">end</span> <span class="token keyword">end</span> <span class="token keyword">module</span> <span class="token constant">DiBangDongCo</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">di</span></span> p <span class="token string">"đi bằng động cơ"</span> <span class="token keyword">end</span> <span class="token keyword">end</span> <span class="token keyword">module</span> <span class="token constant">KhongDiDuoc</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">di</span></span> p <span class="token string">"Không đi được"</span> <span class="token keyword">end</span> <span class="token keyword">end</span> <span class="token keyword">class</span> <span class="token class-name">GauTruc</span> <span class="token operator"><</span> <span class="token constant">Gau</span> <span class="token keyword">include</span> <span class="token constant">DiBangChan</span> <span class="token keyword">end</span> <span class="token keyword">class</span> <span class="token class-name">GauDoChoi</span> <span class="token operator"><</span> <span class="token constant">Gau</span> <span class="token keyword">include</span> <span class="token constant">DiBangDongCo</span> <span class="token keyword">end</span> <span class="token keyword">class</span> <span class="token class-name">GauBong</span> <span class="token operator"><</span> <span class="token constant">Gau</span> <span class="token keyword">include</span> <span class="token constant">KhongDiDuoc</span> <span class="token keyword">end</span> gau_truc <span class="token operator">=</span> <span class="token constant">GauTruc</span><span class="token punctuation">.</span><span class="token keyword">new</span> gau_truc<span class="token punctuation">.</span>di gau_do_choi <span class="token operator">=</span> <span class="token constant">GauDoChoi</span><span class="token punctuation">.</span><span class="token keyword">new</span> gau_do_choi<span class="token punctuation">.</span>di gau_bong <span class="token operator">=</span> <span class="token constant">GauBong</span><span class="token punctuation">.</span><span class="token keyword">new</span> gau_bong<span class="token punctuation">.</span>di |
=> Tuy các phần biến đổi được được tách ra thành các module độc lập, nhưng việc mở rộng vẫn còn phức tạp do phải tạo ra các subclass kế thừa từ superclass
Cách 3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | <span class="token keyword">class</span> <span class="token class-name">Gau</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">initialize</span></span> loai_gau <span class="token variable">@gau</span> <span class="token operator">=</span> loai_gau<span class="token punctuation">.</span><span class="token keyword">new</span> <span class="token keyword">end</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">di</span></span> <span class="token variable">@gau</span><span class="token punctuation">.</span>di <span class="token keyword">end</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">hien_thi</span></span> p <span class="token string">"Hiển thị"</span> <span class="token keyword">end</span> <span class="token keyword">end</span> <span class="token keyword">module</span> <span class="token constant">Loai</span> <span class="token keyword">class</span> <span class="token class-name">GauTruc</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">di</span></span> p <span class="token string">"đi bằng chân"</span> <span class="token keyword">end</span> <span class="token keyword">end</span> <span class="token keyword">class</span> <span class="token class-name">GauDoChoi</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">di</span></span> p <span class="token string">"đi bằng động cơ"</span> <span class="token keyword">end</span> <span class="token keyword">end</span> <span class="token keyword">class</span> <span class="token class-name">GauBong</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">di</span></span> p <span class="token string">"Không đi được"</span> <span class="token keyword">end</span> <span class="token keyword">end</span> <span class="token keyword">end</span> gau_truc <span class="token operator">=</span> <span class="token constant">Gau</span><span class="token punctuation">.</span><span class="token keyword">new</span> <span class="token constant">Loai</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">GauTruc</span> gau_truc<span class="token punctuation">.</span>di gau_do_choi <span class="token operator">=</span> <span class="token constant">Gau</span><span class="token punctuation">.</span><span class="token keyword">new</span> <span class="token constant">Loai</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">GauDoChoi</span> gau_do_choi<span class="token punctuation">.</span>di gau_bong <span class="token operator">=</span> <span class="token constant">Gau</span><span class="token punctuation">.</span><span class="token keyword">new</span> <span class="token constant">Loai</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">GauBong</span> gau_bong<span class="token punctuation">.</span>di |
=> Đến đây ta thấy không còn việc kế thừa giữa các class nữa và việc khởi tạo một object rõ ràng hơn. Nếu muốn mở rộng chỉ cần thêm các class cần thiết vào trong module “Loai”. Việc bảo trì, mở rộng trở nên rất dễ dàng.