Mẫu thiết kế được phơi bày: Mẫu chiến lược



Trong blog này, chúng tôi sẽ khám phá Mô hình thiết kế chiến lược, được sử dụng để tạo một nhóm thuật toán có thể hoán đổi cho nhau và có thể được chọn động.

'

Chào mừng bạn đến với bài đăng đầu tiên của loạt bài “Thiết kế mẫu phơi bày”. Trong loạt bài này, chúng tôi sẽ khám phá từng Mẫu thiết kế từ đầu.





Chỉ đơn giản biết một ngôn ngữ lập trình và các cấu trúc của nó sẽ không giúp bạn trở thành một lập trình viên hoặc nhà phát triển tốt hơn. Nó đòi hỏi kiến ​​thức về Mẫu thiết kế để tạo ra phần mềm hoạt động ngày hôm nay và cả trong tương lai.

Nhiều nhà phát triển đã gặp phải những vấn đề thiết kế mà bạn đang phải đối mặt ngay bây giờ hoặc sẽ phải đối mặt trong tương lai. Họ đã chỉ định một cách tiêu chuẩn để giải quyết vấn đề đó. Vì vậy, bằng cách sử dụng Mẫu thiết kế, bạn có được lợi thế của việc sử dụng các kỹ thuật đã được chứng minh.



Mỗi Mẫu thiết kế là để giải quyết một loại tình huống cụ thể, có thể có những tình huống có thể sử dụng nhiều Mẫu thiết kế.

Hầu hết các lập trình viên chỉ cố gắng giải quyết vấn đề mà họ phải đối mặt mà không bận tâm đến các mẫu thiết kế, mã thừa hoặc thậm chí là các khớp nối chặt chẽ. Nhưng những lập trình viên giỏi lại bắt đầu khác. Họ nghĩ về các yêu cầu của ngày hôm nay, các yêu cầu trong tương lai, việc duy trì mã và khả năng tái sử dụng của mã.

Các lập trình viên giỏi không vội vàng bắt đầu viết mã khi họ nhận được yêu cầu. Họ ngồi và suy nghĩ về vấn đề liệu thiết kế của họ có hiệu quả hay không. Nếu có, liệu nó sẽ hoạt động sau 6 tháng, khi các yêu cầu sẽ thay đổi.



Các lập trình viên giỏi lấy giấy bút của họ và bắt đầu thiết kế các lớp của họ và mối quan hệ giữa các lớp. Họ cố gắng tạo ra sự liên kết lỏng lẻo và tính liên kết cao trong thiết kế của họ, trong khi thực hiện tất cả những điều này, họ luôn có Nguyên tắc hướng đối tượng trong tâm trí. Họ không đi vào bên trong mã cấp thấp ngay lập tức. Để thiết kế phần mềm linh hoạt và có thể tái sử dụng, bạn nên làm theo cách tiếp cận này, nếu không bạn sẽ luôn thấy mình phải sửa đổi mã mà bạn đã viết trước đó.

Chỉ có một thứ không đổi trong ngành phần mềm và đó là Thay đổi. Các yêu cầu chắc chắn sẽ tiếp tục thay đổi. Vậy làm cách nào để chúng tôi thiết kế phần mềm mà mã của bạn có thể dễ dàng thích ứng với các yêu cầu trong tương lai? Vì vậy, bạn phải bắt đầu sớm và thiết kế nó theo cách mà các yêu cầu trong tương lai không phá vỡ mã trước đó của bạn.

Làm thế nào tôi có thể làm điều đó?

Vâng, nó có thể được thực hiện bằng cách tuân theo Nguyên tắc thiết kế và Mẫu thiết kế dựa trên những nguyên tắc đó.

Bây giờ, hãy đi sâu vào viết mã và bắt đầu hành trình trở thành một lập trình viên giỏi hơn. Trong bài đăng này, chúng tôi sẽ khám phá một trong những mô hình quan trọng nhất - Mô hình chiến lược .

Khi tôi nói điều quan trọng nhất, nó phản ánh vấn đề chung được giải quyết bằng Mô hình chiến lược.

Mô hình chiến lược là gì?

Đây là định nghĩa trực tiếp từ cuốn sách 'Gang of Four': 'Mô hình chiến lược được sử dụng để tạo một nhóm thuật toán có thể hoán đổi cho nhau mà từ đó quy trình bắt buộc được chọn trong thời gian chạy”.

Trong trường hợp bạn làkhông thể hiểu, đừng lo lắng, chúng tôi sẽ giải thích nó trong mộtđơn giản hơnđườngcho bạnhiểu biết.

ngăn xếp và đống bộ nhớ trong java

Đầu tiên chúng ta hãy hiểu vấn đề và sau đó chúng ta sẽ xem cách Mô hình chiến lược có thể giải quyết vấn đề đó.

Trong sơ đồ UML ở trên, chúng ta có lớp trừu tượng Động vật và hai lớp cụ thể, Chó và Chim, mở rộng từ siêu lớp Động vật.

Vì vậy, hãy xác định một lớp trừu tượng Động vật và hai lớp cụ thể, Chó và Chim.

Bạn nghĩ gì về thiết kế trên? Có một sai lầm lớn trong thiết kế của chúng tôi.

Tất cả các loài động vật không thể bay, như trong trường hợp trên, một con chó không thể bay. Nhưng nó vẫn có hành vi ‘bay’.

Chúng tôi đã mắc lỗi khi viết phương thức trừu tượng fly () bên trong lớp Animal. Thiết kế này sẽ buộc mỗi lớp con Dog, Bird, Penguin, Crocodile, Goose, v.v. phải thực hiện phương thức fly ().

Đáng lẽ chúng ta phải hiểu rằng bay là một khả năng mà không phải loài động vật nào cũng có được. Bằng cách cung cấp phương thức fly () trong lớp trừu tượng Động vật, chúng ta đã thiết lập khả năng bay trong tất cả các lớp con, điều này không đúng cho tất cả các lớp con của động vật.

Bạn có thể nghĩ rằng có vấn đề gì khi triển khai phương thức bay trong các lớp con. Mặc dù bạn có thể triển khai phương thức fly () trong các lớp con Động vật không bay để chỉ in “Tôi không thể bay”. Nhưng vấn đề là, bạn vẫn đang cho những động vật không bay được tập tính của ruồi. Điều này LAF không đúng.

Bạn cảm thấy thế nào khi gọi dog.fly () hoặc sấu.fly ().

Vì vậy, bây giờ chúng ta đã hiểu rằng thiết kế của chúng ta không đúng và chúng ta nên loại bỏ phương thức fly () khỏi lớp con Animal.

Cách khác để thiết kế các lớp của chúng tôi theo cách mà thiết kế của chúng tôi không bắt buộc tất cả các lớp con Động vật phải có hành vi ruồi.

Một giải pháp được nghĩ đến ngay lập tức là chúng ta có thể tạo một giao diện bay bằng phương pháp bay và chỉ những động vật có thể bay mới thực hiện giao diện bay đó. Bằng cách này, chúng tôi sẽ không thực thi tất cả các lớp con Động vật để xác định hành vi của ruồi. Vì vậy, hãy viết mã phương pháp thiết kế này.

Bây giờ, lớp Animal của chúng ta sẽ giống như đoạn mã dưới đây sau khi xóa phương thức fly khỏi lớp Animal.

Bây giờ, hãy xác định giao diện Bay

sắp xếp danh sách c ++

Bây giờ, lớp Chó sẽ được thay đổinhưmã bên dưới và nó không cần phải có hành vi bay.

Hãy xem một số lớp con Động vật của chúng ta sẽ có tập tính bay.

Chúng tôi đã giải quyết được vấn đề trước đây của mình, nhưng chúng tôi lại gặp phải một rắc rối mới và đó là 'Sao chép mã'.

Giả sử, chúng ta sẽ có 100 lớp phụ Động vật bay khác nhau. Chúng ta phải sao chép mã cho hành vi bay vì giao diện bay không thể cung cấp bất kỳ triển khai nào cho hành vi bay và sau này nếu chúng ta muốn thay đổi triển khai phương thức fly () trong bất kỳ lớp con nào, chúng ta sẽ phải mở lớp đó và thay đổi mã, đó là xấu. Chúng ta đang thiếu một thứ gì đó lớn lao và tức là chúng ta không thể thay đổi hành vi bay của một lớp trong thời gian chạy.

Nhưng đừng lo lắng, Mô hình Chiến lược sẽ giúp bạn thoát khỏi vấn đề này.

Vì vậy, hãy cấu trúc lại mã của chúng tôi để sử dụng Mẫu chiến lược.

Giao diện bay sẽ vẫn như cũ. Bây giờ, thay vì mỗi lớp phụ bay tự thực hiện giao diện bay, chúng ta sẽ xác định các lớp cụ thể riêng biệt sẽ thực hiện các hành vi bay khác nhau. Hãy xem cách thực hiện điều đó.

Vì vậy, tất cả hoạt động như thế nào, hãy cùng xem TestClass

Bằng cách sử dụng Mô hình chiến lược, giờ đây, chúng tôi có thể thay đổi hành vi bay của bất kỳ động vật nào tại thời điểm chạy và điều đó mà không cần thực thi bất kỳ lớp con nào để chỉ định chính hành vi bay.

Khi nào sử dụng Mô hình chiến lược?

Khi bạn muốn có thể thay đổi động hành vi tại thời điểm chạy.

Để đảm bảo bạn hiểu rõ ràng về Mẫu chiến lược, hãy lấy một ví dụ khác.

Trong lớp Nhân viên ở trên, chúng tôi đang đặt mức lương của nhân viên tùy thuộc vào sự chỉ định của họ. Nếu nhân viên là “Thực tập sinh”, chúng tôi sẽ cộng thêm 10% tiền thưởng vào lương cơ bản để tính lương thực tế.

Nếu một nhân viên là “Nhà phát triển web”, chúng tôi sẽ cộng thêm 20% tiền thưởng vào lương cơ bản để tính lương thực tế và quy trình tương tự sẽ diễn ra đối với các loại nhân viên khác. Mặc dù thuật toán của chúng tôi để tính toán lương thực tế rất đơn giản để dễ hiểu hơn nhưng hầu hết thời gian, nó bao gồm nhiều phép so sánh và tính toán.

Vì vậy, có gì sai với mã cấp nhân viên?

Mã để tính lương (getPay ()) là tĩnh. Giả sử tôi muốn thay đổi tiền thưởng cho “Thực tập sinh” từ 10% thành 14%. Tôi sẽ phải mở mã hạng Nhân viên và thay đổi nó.

Và một vấn đề khác là tôi không thể thay đổi thuật toán trả lương của nhân viên tại thời điểm chạy. Vì vậy, làm thế nào để làm điều đó? Mô hình chiến lược được sử dụng đặc biệt để xử lý loại vấn đề này.

Hãy cấu trúc lại mã để sử dụng Mẫu chiến lược.

lấy kích thước của mảng javascript

Tôi sẽ xác định một số thuật toán để tính toán lương. Sau đó, tôi sẽ có thể sử dụng bất kỳ thuật toán nào trong số này để tính toán khoản thanh toán tại thời điểm chạy.

Bây giờ, hãy xem lớp Nhân viên sẽ thay đổi như thế nào.

Ghi chú: Tôi đã xóa logic tính toán lương khỏi lớp Nhân viên và tạo một phương thức PayAlgorithm () đã đặt mà qua đó tôi sẽ đặt PayAlgorithm mà tôi muốn sử dụng để tính lương.

Điều này sẽ giúp tôi linh hoạt trong việc tính toán khoản thanh toán bằng cách chỉ định động bất kỳ Thuật toán PayAl nào tại thời điểm chạy. Ngoài ra, lưu ý rằng sau này nếu tôi phải thay đổi logic tính toán khoản thanh toán, tôi có thể tạo Thuật toán PayAl mới và sử dụng thuật toán đó để tính toán khoản thanh toán. Tôi không cần phải thay đổi mã trước đó, thật tuyệt phải không?

Vì vậy, hãy xem nó hoạt động.

Tôi hy vọng bạn đã hiểu rất rõ về Mô hình Chiến lược. Cách tốt nhất để học điều gì đó là thực hành.

Trong trường hợp bạn có bất kỳ câu hỏi nào liên quan đến Mô hình Chiến lược hoặc bất kỳ Mô hình nào khác, hãy để lại câu hỏi của bạn bên dưới.

Hãy theo dõi bài đăng tiếp theo, nơi chúng tôi sẽ khám phá một trong những Mẫu thiết kế phổ biến nhất, Mẫu nhà máy.

Cho đến lúc đó, bạn có thể tải xuống đoạn mã chơi với nó và đảm bảo rằng bạn đã củng cố Mô hình Chiến lược trong đầu.

Có một câu hỏi cho chúng tôi? Đề cập đến họ trong phần bình luận và chúng tôi sẽ liên hệ lại với bạn.

Bài viết liên quan: