Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 93 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
93
Dung lượng
3,73 MB
Nội dung
lOMoARcPSD|13013005 DESIGN PATTERN FOR BEGINNER PHẦN 1: TỔNG QUAN VỀ DESIGN PATTERN ĐỘI NGŨ BIÊN TẬP Nguyễn Khắc Nhật Nguyễn Bình Sơn Nguyễn Khánh Tùng Phan Văn Luân LỜI TỰA Làm ngành công nghiệp phát triển phần mềm, bạn ã gặp phải trường hợp này? Bạn làm qua nhiều dự án khác nhận rằng, dự án ó, ln dùng phương pháp, cách làm theo khn mẫu ó ể giải vấn ề gặp phải, chúng tương ồng với ây thứ thường xun Lặp lại, lặp lại… Nếu có, ó lúc mà bạn cần ến Design Pattern! Được xây dựng theo dạng “template” - Design pattern giải pháp tổng thể ã ược tối ưu hóa, ược tái sử dụng cho vấn ề phổ biến thiết kế phần mềm mà thường gặp phải hàng ngày Đây tập giải pháp ã ược suy nghĩ, ã giải tình cụ thể Tiếp theo ây, bạn có nghĩ phù hợp ể ọc eBook này? Điều quan trọng tơi muốn nói rằng: Design Pattern khơng dành cho bạn bắt ầu tìm hiểu lập trình Muốn tìm hiểu học ược Design Pattern, bạn cần nắm ược kiến thức OOP ặc biệt abstract class, interface static Khơng dành cho người tìm hiểu lập trình, tựa sách lại “for Beginners” Ở ây, muốn em người mới, kẻ “dummy” ến với Design Pattern Họ người bắt ầu làm quen với “mẫu” áp dụng ể phát triển kỹ năng, tay nghề mình! -Những nội dung ây kiến thức ược tổng hợp biên tập lại từ ội ngũ sản xuất Bằng tất nỗ lực ể em tới kiến thức thực cần thiết trọng tâm cho người bắt ầu tìm hiểu Design Pattern Trong q trình biên tập, khơng tránh khỏi sai sót, mong nhận ược óng góp anh, chị, em ể eBook ược hoàn thiện Thân mến, Đội ngũ biên tập! MỤC LỤC Bài 1: Design pattern gì? Error! Bookmark not defined Protected: Design Pattern gì? Design Principle Bài Design Pattern iều khơng thể bỏ qua Design Pattern gì? 10 Điều khiến Design Pattern trở nên quan trọng? 10 Để học ược Design Pattern, bạn cần gì? 12 Các loại Design Pattern 12 Bạn có hứng thú với Design Pattern? 13 Bài Nhập môn Design Pattern theo phong cách kiếm hiệp 14 Nhập ề 14 Hỏi gian DS chi, mà bọn Dev thề nguyền sống chết 15 Design Pattern Kiếm Phổ 16 Khẩu nhập môn Design Pattern 17 Thay lời kết 18 Bài 4: Design Pattern tiến hóa lập trình 18 Singleton Pattern 20 Factory Pattern 23 Composite pattern 27 Strategy pattern 32 Model - View - Controller MVC 37 Lời kết 43 Bài Design Patterns: Best Practices for Application Development 43 23 Gang of Four Design Patterns 45 Bài Vỡ lòng nguyên tắc thiết kế SOLID 46 Kiến trúc 47 Nguyên tắc thiết kế 47 SOLID 47 Nguyên tắc Đơn Trách Nhiệm 48 Nguyên Tắc Đóng/Mở 52 Nguyên Tắc Thay Thế Liskov 56 Nguyên Tắc Phân Tách Giao Diện 60 Nguyên Tắc Đảo Ngược Phụ Thuộc 62 Kết luận 63 Bài Sự khác biệt thiết kế tốt thiết kế tồi kỹ thuật phần mềm 64 Bài Giải thích mơ hình MVC thơng qua cốc trà 66 Nếu bạn i uống trà á, bạn ã hiểu ược MVC 66 Mơ hình MVC gì? 66 Bài học rút gì? 68 Quay trở lại vấn ề lập trình web 69 Tổng kết 69 Bài Sự khác biệt mẫu thiết kế MVC MVT 69 Mẫu thiết kế MVC (Model-View-Controller) 69 Mẫu thiết kế MVT (Model-View-Template): 70 Bài 10 Kiến trúc lục giác Java 71 Bài 11 Những Design Pattern thường dùng Android 80 Lời mở ầu 80 Phân loại design pattern 80 Structural Patterns 83 Behavioral Patterns 85 Kết luận 86 lOMoARcPSD|13013005 Bài 1: Design pattern gì? Protected: Design Pattern gì? Bắt ầu với ứng dụng mô Duck ơn giản: Nam làm việc cho công ty mơ game có tên SimUDuck Game thể nhiều trạng thái khác vịt hành vi bơi tiếng kêu Thiết kế ban ầu sử dụng hướng ối tượng (OO) cách tạo class Duck làm class cha ể cho lớp thừa kế Vào cuối năm, áp lực gay gắt với ối thủ cạnh tranh Sau tuần suy xét cẩn trọng giám ốc ịnh phải tạo bước ột phá Các vịt cần phải biết bay Những vịt biết bay chìa khố ột phá ể giúp ánh bại ối thủ cạnh tranh vịt biết bơi Và ương nhiên, quản lí Nam OK vấn ề này, nói làm tuần xong Và ây công việc Nam: Mình cần thêm method fly() vào lớp Duck (parent class) cho tất lớp thừa kế xong ngay! lOMoARcPSD|13013005 Nhưng có vấn ề xảy ra: Giám ốc iện thoại cho Nam: “Cậu ùa với ah, ang chạy demo cậu: Những vịt cao su biết bay!” Nam quên iều vịt cao su bay Và anh nhận iều rằng, kế thừa khơng giúp nhiều việc tái sử dụng, bảo trì code Cùng xem xét lại kế thừa Vì vịt cao su có tiếng kêu khác với vịt thường, vịt cao su bay ược Chúng ta phải Override lại hàm quack() (kêu) hàm fly() (bay) vịt cao su Downloaded by Thi Hoa Nguyen (tungmt.300499@gmail.com) lOMoARcPSD|13013005 Nhưng vịt gỗ (WoodenDuck) chúng khơng thể kêu bay ược? Interface nào? Nam nhận rằng, kế thừa làm mã lặp lại (duplicate code), khơng thích hợp cho mã bị thay ổi thường xuyên Trong ó hàm fly() quack() bị ảnh hưởng yêu cầu Nam ịnh ập lại mã cách: em hàm fly() quack() khỏi class Duck tạo interface Flyable với hàm fly() interface Quackable với hàm quack() Chỉ vịt bay implement interface Flyable, vịt phát tiếng kêu implement interface Quackable Nhưng giải cách kết tồi tệ Theo cách kế thừa: bạn cần override lại vài hàm Theo cách interface: bạn phải override lại tất vịt bay phát tiếng kêu, ta có 70 vịt thế… Bạn làm bạn Nam? Chúng ta biết tất lớp kế thừa hàm fly() quack(), kế thừa khơng phải áp án úng Cịn với interface, có nhiều class implement lại hàm fly, quack() interface Flyable Quackable, iều hạn chế lại việc tái sử dụng code Và ó cần Design Pattern lOMoARcPSD|13013005 Design Principle Identify the aspects of your application that vary and separate them from what stays the same Tạm dịch là: Tìm phần hay thay ổi ứng dụng óng gói chúng, ể không ảnh hưởng tới phần chung hệ thống Thiết kế hành vi (behavior) cho vịt Nam nhận rằng, hàm fly() quack() thay ổi thường xuyên nên ược óng gói riêng biệt Downloaded by Thi Hoa Nguyen (tungmt.300499@gmail.com) lOMoARcPSD|13013005 Miền (Domain): Nó lớp logic nghiệp vụ cốt lõi chi tiết triển khai lớp bên ược ẩn với lớp Ứng dụng (Application): Nó hoạt ộng trung gian lớp Miền lớp Khung Khung (Framework): Lớp có tất chi tiết triển khai mà lớp miền tương tác với giới bên ngồi Ví dụ minh họa: Hãy hiểu kiến trúc ví dụ thời gian thực Chúng ta thiết kế ứng dụng Cake Service Spring Boot Bạn tạo dự án dựa Spring Maven bình thường, tùy thuộc vào thuận tiện bạn Sau ây phần khác ví dụ: Miền: Cốt lõi ứng dụng Tạo lớp Cake với thuộc tính nó, ể ơn giản, thêm tên vào ây // Consider this as a value object // around which the domain logic revolves public class Cake implements Serializable { 73 lOMoARcPSD|13013005 private static final long serialVersionUID = 100000000L; private String name; // Getters and setters for the name public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Cake [name=" + name + "]"; } } Cổng ến (Inbound Port): Xác ịnh giao diện mà qua ó ứng dụng cốt lõi kích hoạt giao tiếp Nó ưa ứng dụng cốt lõi giới bên import java.util.List; // Interface through which the core // application communicates For // all the classes implementing the // interface, we need to implement // the methods in this interface public interface CakeService { public void createCake(Cake cake); public Cake getCake(String cakeName); public List listCake(); } Cổng i (Outbound Port): Tạo thêm giao diện ể tạo truy cập giới bên import java.util.List; // Interface to access the cake interface CakeRepository { public public void createCake(Cake cake); public Cake getCake(String cakeName); 74 Downloaded by Thi Hoa Nguyen (tungmt.300499@gmail.com) lOMoARcPSD|13013005 public List getAllCake(); } Bộ iều hợp (Primary Adapter): Bộ iều khiển iều hợp chúng ta, cung cấp iểm cuối ể tạo tìm nạp tài nguyên import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; // This is the REST endpoint @RestController @RequestMapping("/cake") public class CakeRestController implements CakeRestUI { @Autowired private CakeService cakeService; @Override public void createCake(Cake cake) { cakeService.createCake(cake); } @Override public Cake getCake(String cakeName) { return cakeService.getCake(cakeName); } Chúng ta tạo thêm giao diện cho CakeRestUI sau: import java.util.List; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; public interface CakeRestUI { @PostMapping void createCake(@RequestBody Cake cake); @GetMapping("/{name}") public Cake getCake(@PathVariable String name); @GetMapping public List listCake(); } 75 lOMoARcPSD|13013005 Bộ iều hợp thứ cấp (Secondary Adapter): Đây việc triển khai cổng i Vì CakeRepository cổng gửi i chúng ta, triển khai import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import org.springframework.stereotype.Repository; // Implementing the interface and // all the methods which have been // defined in the interace @Repository public class CakeRepositoryImpl implements CakeRepository { private Map cakeStore = new HashMap(); @Override public void createCake(Cake cake) { cakeStore.put(cake.getName(), cake); } @Override public Cake getCake(String cakeName) { return cakeStore.get(cakeName); } @Override public List getAllCake() { return cakeStore.values().stream().collect(Collectors.toList()); } } Giao tiếp lõi với Nguồn liệu: Cuối cùng, tạo lớp triển khai chịu trách nhiệm giao tiếp ứng dụng lõi với nguồn liệu cách sử dụng cổng import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; // This is the implementation class // for the CakeService @Service 76 Downloaded by Thi Hoa Nguyen (tungmt.300499@gmail.com) lOMoARcPSD|13013005 public class CakeServiceImpl implements CakeService { // Overriding the methods defined // in the interface @Autowired private CakeRepository cakeRepository; @Override public void createCake(Cake cake) { cakeRepository.createCake(cake); } @Override public Cake getCake(String cakeName) { return cakeRepository.getCake(cakeName); } @Override public List listCake() { return cakeRepository.getAllCake(); } } Cuối ã triển khai tất phương thức ược yêu cầu ví dụ ã cho Sau ây kết chạy oạn mã trên: 77 lOMoARcPSD|13013005 Bây giờ, tạo số Cake cho ví dụ API REST API sau ược sử dụng ể ẩy Cake vào kho lưu trữ (repository) Vì ang tạo thêm liệu, sử dụng POST request Ví dụ: 78 Downloaded by Thi Hoa Nguyen (tungmt.300499@gmail.com) lOMoARcPSD|13013005 Ưu iểm kiến trúc Lục giác: ● Dễ bảo trì: Vì logic ứng dụng cốt lõi (các lớp ối tượng) ược cách ly với giới bên ược liên kết lỏng lẻo, nên việc bảo trì dễ dàng Sẽ dễ dàng ể thêm số tính vào hai lớp mà không cần chạm vào lớp ● Dễ dàng iều chỉnh thay ổi mới: Vì tất lớp ều ộc lập muốn thêm thay sở liệu mới, cần thay thêm iều hợp sở liệu mà không cần thay ổi miền logic ứng dụng ● Dễ dàng kiểm thử: Việc kiểm thử trở nên dễ dàng Chúng ta viết trường hợp thử nghiệm cho lớp cách mô cổng iều hợp giả (mock adapters) 79 lOMoARcPSD|13013005 Bài 11 Những Design Pattern thường dùng Android Lời mở ầu Trong q trình thực dự án, ngồi việc làm thoả mãn yêu cầu khách hàng, việc viết code cách rõ ràng, (clean code) iều vơ quan trọng Có thể tương lai bạn phải phát triển chức mà kế thừa lại code cũ củabạn, chí trình maintain phải ọc lại code việc viết code cách “sạch sẽ” giúp công việc sau trở nên dễ dàng phát sinh bug Design patterns giải pháp ã ược tối ưu hóa, ược tái sử dụng cho vấn ề lập trình mà gặp phải hàng ngày Nó khn mẫu ã ược suy nghĩ, giải tình cụ thể Các vấn ề mà bạn gặp phải bạn tự nghĩ cách giải chưa phải tối ưu Design Pattern giúp bạn giải vấn ề cách tối ưu nhất, cung cấp cho bạn giải pháp lập trình OOP Nó khơng phải ngôn ngữ cụ thể Design Patterns thực ược phần lớn ngơn ngữ lập trình Ta thường gặp lập trình OOP Trong viết tơi xin giới thiệu số design pattern thường sử dụng Android Phân loại design pattern Có nhóm sau: ● ● ● Creational Pattern (nhóm khởi tạo) Builder, Dependency Injection, Singleton… Nó giúp bạn việc khởi tạo ối tượng Structural Pattern (nhóm cấu trúc) Adapter, Facade… Nó dùng ể thiết lập, ịnh nghĩa quan hệ ối tượng Behavioral Pattern (nhóm hành vi) Command, Observer, Model View Controller, Model View View Model Nhóm dùng thực hành vi ối tượng Ta i tìm hiểu cụ thể loại design pattern Creational Pattern 80 Downloaded by Thi Hoa Nguyen (tungmt.300499@gmail.com) lOMoARcPSD|13013005 Builder Builder design pattern phân chia việc khởi tạo (construction) tổng thể ối tượng phức tạp làm nhiều phần nhỏ Tức làthay tạo construction cho ối tượng phức tạp tạoconstruction cho phần ặc trưng ối tượng ó Trong Android, Builder design pattern xuất sử dụngnhững ối tượng AlertDialog.Builder new AlertDialog.Builder(this) setTitle("Metaphorical Sandwich Dialog") setMessage("Metaphorical message to please usethe spicy mustard.") setNegativeButton("No thanks", newDialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { // "No thanks" button wasclicked } }) setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { // "OK" button was clicked } }) show(); Cách dùng thực bước một, bước giúp ta khởi tạo ược phần cụ thể ối tượng AlertDialog Đoạn code tạo dialog hình dưới: 81 lOMoARcPSD|13013005 Dependency Injection Dependency Injection giống việc di chuyển vào ngơi nhà ã có ầy ủ ạc nội thất Ta không cần chuẩn bị mà việc dùng luônnhững sẵn có Nó cung cấp ối tượng mà bạn yêu cầu bạn muốn khởi tạo nhanh ối tượng mới, ối tượng không cần xây dựng hay tuỳ chỉnh nhữngthành phần Trong Android, ôi ta cần truy cập ến ối tượng phức tạp từ nhiều iểm ứng dụng, ví dụ như: network client, image loader, SharedPreferences hay local storage Ta inject ối tượng ó vào Activity Fragment truy cập chúng cần Dagger open-source dependency injection frameworkthường ược sử dụng Android, ược phát triển cộng tác Google Square Với Dagger 2, bạn thích ơn giản class với @Module annotation dần bổ sung method với @Provides annotation ví dụdưới ây: public class AppModule { @Provides SharedPreferences provideSharedPreferences(Application app) { return app.getSharedPreferences("prefs", Context.MODE_PRIVATE); } } Các module bên tạo cấu hình tất ối tượng cần thiết Nó giúp ích q trình xây dựng ứng dụng lớn, ta có thểtạo module tuỳ theo chức Sau ó, ta tạo Component interface ể liệt kê module class mà ta inject @Component(modules = AppModule.class) interface AppComponent { } Cuối cùng, ta sử dụng @Injectannotation ể request ến dependency cần ến @Inject SharedPreferences sharedPreferences; Như ví dụ trên, cách tiếp cận Activity giúp ơngiản việc sử dụng SharedPreferences ể lưu trữ cục bộ, mà Activity không cần biết SharedPreference ược khởi tạo chuyển ến Bạn tìm hiểu thêm Dagger theo link: https://google.github.io/dagger/ Singleton 82 Downloaded by Thi Hoa Nguyen (tungmt.300499@gmail.com) lOMoARcPSD|13013005 Singleton Design Patter ịnh tồn instance class ó tồn chương trình Nó ược dùngkhi ta muốn mơ hình hoá ối tượng cụ thể giới thực có instance public class ExampleSingleton { private static ExampleSingleton instance = null; private ExampleSingleton() { // customize if needed } public static ExampleSingleton getInstance() { if (instance == null) { instance = new ExampleSingleton(); } return instance; } } Trong oạn code trên, method getInstance ảm bảo bạnchỉ khởi tạo ối tượng class lần Để truy cập ến singleton bạn cận gọi: ExampleSingleton.getInstance(); Structural Patterns Adapter Adapter design pattern cho phép lớp khơng tương thích làmviệc ược cách chuyển ổi giao diện (interface) lớp sang giao diện khác phù hợp với yêu cầu khách hàng Ví dụ ta muốn hiển thị danh sách ối tượng cho tương thích với view public class TribbleAdapter extends RecyclerView.Adapter { private List mTribbles; public TribbleAdapter(List tribbles) { this.mTribbles = tribbles; } @Override public TribbleViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext()); View view = inflater.inflate(R.layout.row_tribble, viewGroup, false); return new TribbleViewHolder(view); } @Override public void onBindViewHolder(TribbleViewHolder viewHolder, int i) { viewHolder.configure(mTribbles.get(i)); } @Override 83 lOMoARcPSD|13013005 public int getItemCount() { return mTribbles.size(); } } RecyclerView khơng biết Tribble gì, khơng bao giờthấy cụ thể, ó cơng việc Adapter Adapter có nhiệm vụ xử lý liệu Tribble gửi cấu hình xác n ViewHolder Facade Faỗade design pattern cung cp cỏc high level interface ể interface khác dễ sử dụng Nếu Activity bạn cần danh sách Book, yêu cầu ối tượng cho danh sách ó mà khơng hiểu hoạt ộng bên lưu trữ cục bộ, nhớ cache API Nó giữ cho oạn mã ược rõ ràng, mà không làm thay ổi hoạt ộng Activity Sau cần, ta thay ổi API mà không làm ảnh hưởng ến tác ộng mà thực Retrofit Open Source ca Square s giỳp ta thc thi Faỗade design pattern Client ơn giản gọi listBook() method ể nhận ược danh sách Book callback Điều cho phép ta thực iều chỉnh bên mà khơng ảnh hưởng ến client Ví dụ: bạn ịnh deserializer JSON tùy chỉnh: RestAdapter restAdapter = new RestAdapter.Builder() setConverter(new MyCustomGsonConverter(new Gson())) setEndpoint("http://www.myexampleurl.com") build(); 84 Downloaded by Thi Hoa Nguyen (tungmt.300499@gmail.com) lOMoARcPSD|13013005 return restAdapter.create(BooksApi.class); Mỗi ối tượng biết diễn sau ó (ít phụ thuộc lẫn nhau) ta sẽcàng dễ việc sửa iều chỉnh ứng dụng sau Behavioral Patterns Command Command design pattern giúp ta phát hành i request mà khơng cần biết người nhận.Ta óng gói yêu cầu ối tượng gửi i Việc thực yêu cầu chế khác không quan tâm ây EventBus Greenrobot thư viện opensource phổ biến hỗ trợ design pattern Một Event ối tượng kiểu lệnh (command-style) ược kích hoạt user input, server data hay thành phần ứng dụng Ta tạo lớp controng ó mang liệu: public class MySpecificEvent { /* Additional fields if needed */ } Sau ịnh nghĩa kiện, ta có ược instance EventBus ăng ký ối tượng subscriber eventBus.register(this); Giờ ây ối tượng ã subscriber, ta nói cho biết loại event ịnh nghĩa hành ộng nhận ược event ó public void onEvent(MySpecificEvent event) {/* Do something */}; Cuối cùng, tạo ăng kiện ó dựa tiêu chí eventBus.post(event); Observer Observer design pattern xác ịnh phụ thuộc – nhiều ối tượng Khi ối tượng thay ổi trạng thái, ối tượng phụ thuộc ược thơng báo tự ộng cập nhật 85 lOMoARcPSD|13013005 Đây mơ hình linh hoạt, ta sử dụng cho hoạt ộng có thời gian khơng xác ịnh, ví dụ gọi API Ta sử dụng ể phản hồi với input từ người dùng RxAndroid Framework dẫn ta thực pattern xuyên suốt ứng dụng apiService.getData(someData) observeOn(AndroidSchedulers.mainThread()) subscribe (/* an Observer */); Trong thời gian ngắn, ta xác ịnh ối tượng Observable phát giá trị (thơng báo) Các giá trị phát lúc, luồng liên tục, tốc ộ thời gian Các ối tượng Subscriber lắng nghe giá trị phán ứng chúng ến Ví dụ, bạn mở ăng ký (subscribe) gọi API, lắng nghe response từ server thực hành vi tương ứng Model-View-Controller MVC ề cập ến mơ hình kiến trúc ang thống trị nhiều tảng Nó ề cập ến phân chia lớp thành loại: ● ● Model: Các lớp ại diện cho liệu mơ hình cho giới thật ● View: Các lớp trực quan, ang ương việc hiển thị cho người dùng Controller: Là trung gian loại Nó cập nhật View, lấy input từ người dùng thực thay ổi Model Model-View-ViewModel Một kiến trúc giống với MVC Hai thành phần Model View giống với MVC Thành phần ViewModel trung gian View Model, hoạt ộng khác với Controller Thay vào ó cung cấp lệnh cho View bind chúng với Model Khi Model cập nhật, View tương ứng ược cập nhật từ ràng buộc liệu với Model Tương tự người dùng tương tác với View, ràng buộc hoạt ộng theo chiều hướng ngược lại cập nhật lên Model Với mơ hình ta loại bỏ ược nhiều code trung gian ể kết nối Model View Kết luận Trên ây số Design Pattern thường ược sử dụng Android mà biết Nếu bạn có thắc mắc ý kiến vui lòng like comment bên ể trao ổi 86 Downloaded by Thi Hoa Nguyen (tungmt.300499@gmail.com) lOMoARcPSD|13013005 Tài nguyên tham khảo: ● ● ● ● ● ● ● 87 Sách: Head First Design Pattern https://blogs.agilefaqs.com https://viblo.asia https://toidicode.com https://medium.com https://www.codementor.io/@kevinkononenko/model-view-controllermvcexplained-through-ordering-drinks-at-the-bar-i7nupj4oe https://allaravel.com/blog/design-pattern-su-tien-hoa-trong-lap-trinh ... Protected: Design Pattern gì? Design Principle Bài Design Pattern iều khơng thể bỏ qua Design Pattern gì? 10 Điều khiến Design Pattern trở nên quan trọng? 10 Để học ược Design Pattern, bạn cần gì? 12 ... loại Design Pattern 12 Bạn có hứng thú với Design Pattern? 13 Bài Nhập môn Design Pattern theo phong cách kiếm hiệp 14 Nhập ề 14 Hỏi gian DS chi, mà bọn Dev thề nguyền sống chết 15 Design Pattern. .. Pattern Kiếm Phổ 16 Khẩu nhập môn Design Pattern 17 Thay lời kết 18 Bài 4: Design Pattern tiến hóa lập trình 18 Singleton Pattern 20 Factory Pattern 23 Composite pattern 27 Strategy pattern 32 Model