Sự khác biệt giữa mẫu thiết kế Chiến lược và mẫu thiết kế Nhà nước là gì? Tôi đã xem qua khá nhiều bài viết trên web nhưng không thể tìm ra sự khác biệt rõ ràng.
Ai đó có thể vui lòng giải thích sự khác biệt trong các điều khoản của giáo dân?
Sự khác biệt giữa mẫu thiết kế Chiến lược và mẫu thiết kế Nhà nước là gì? Tôi đã xem qua khá nhiều bài viết trên web nhưng không thể tìm ra sự khác biệt rõ ràng.
Ai đó có thể vui lòng giải thích sự khác biệt trong các điều khoản của giáo dân?
Câu trả lời:
Thành thật mà nói, hai mẫu này khá giống nhau trong thực tế và sự khác biệt xác định giữa chúng có xu hướng thay đổi tùy thuộc vào người bạn hỏi. Một số lựa chọn phổ biến là:
Việc triển khai "cổ điển" sẽ phù hợp với Bang hoặc Chiến lược cho mọi mục trong danh sách, nhưng bạn chạy trên các giống lai có kết hợp cả hai. Cho dù một người cụ thể là Nhà nước nhiều hơn hay Chiến lược-y cuối cùng là một câu hỏi chủ quan.
getStatus()
phương thức sẽ trả về các trạng thái khác nhau dựa trên trạng thái của đối tượng, nhưng người gọi phương thức không phải được mã hóa khác nhau để giải thích cho từng trạng thái tiềm năng.Sự khác biệt đơn giản nằm ở chỗ chúng giải quyết các vấn đề khác nhau:
Các cấu trúc để đạt được các mục tiêu khác nhau này tuy nhiên rất giống nhau; cả hai mẫu là ví dụ về thành phần với ủy quyền.
Một số quan sát về lợi thế của họ:
Bằng việc sử dụng nước hoa văn các (context) lớp nhà cầm bớt sau khi dùng từ hiểu biết về những gì nhà nước hoặc gõ nó là gì và những gì khẳng định hoặc loại có sẵn. Điều này có nghĩa là lớp tuân thủ nguyên tắc thiết kế đóng mở (OCP): lớp được đóng để thay đổi trạng thái / loại có, nhưng trạng thái / loại được mở cho các phần mở rộng.
Bằng cách sử dụng mẫu Chiến lược , lớp sử dụng thuật toán (bối cảnh) được giải tỏa khỏi kiến thức về cách thực hiện một tác vụ nhất định (- "thuật toán"). Trường hợp này cũng tạo ra sự tuân thủ OCP; lớp được đóng để thay đổi về cách thực hiện nhiệm vụ này, nhưng thiết kế rất mở đối với việc bổ sung các thuật toán khác để giải quyết nhiệm vụ này.
Điều này cũng có khả năng cải thiện sự tuân thủ của lớp bối cảnh với nguyên tắc trách nhiệm duy nhất (SRP). Hơn nữa, thuật toán trở nên dễ dàng có sẵn để sử dụng lại bởi các lớp khác.
Ai đó có thể vui lòng giải thích trong các điều khoản của giáo dân?
Các mẫu thiết kế không thực sự là khái niệm "cư sĩ", nhưng tôi sẽ cố gắng làm cho nó rõ ràng nhất có thể. Bất kỳ mẫu thiết kế có thể được xem xét trong ba chiều:
Hãy so sánh Nhà nước và Chiến lược.
Trạng thái được sử dụng trong một trong hai trường hợp [sách GoF p. 306] :
- Hành vi của một đối tượng phụ thuộc vào trạng thái của nó và nó phải thay đổi hành vi của nó trong thời gian chạy tùy thuộc vào trạng thái đó.
- Các hoạt động có các câu lệnh điều kiện lớn, nhiều phần phụ thuộc vào trạng thái của đối tượng. Trạng thái này thường được đại diện bởi một hoặc nhiều hằng số liệt kê. Thông thường, một số hoạt động sẽ chứa cấu trúc có điều kiện tương tự. Mẫu trạng thái đặt mỗi nhánh của điều kiện trong một lớp riêng biệt. Điều này cho phép bạn coi trạng thái của đối tượng là một đối tượng theo cách riêng của nó có thể thay đổi độc lập với các đối tượng khác.
Nếu bạn muốn chắc chắn rằng bạn thực sự có vấn đề mà mẫu Trạng thái giải quyết, bạn sẽ có thể mô hình hóa các trạng thái của đối tượng bằng máy trạng thái hữu hạn . Bạn có thể tìm thấy một ví dụ áp dụng ở đây .
Mỗi chuyển đổi trạng thái là một phương thức trong giao diện Trạng thái. Điều này ngụ ý rằng đối với một thiết kế, bạn phải khá chắc chắn về sự chuyển đổi trạng thái trước khi bạn áp dụng mô hình này. Mặt khác, nếu bạn thêm hoặc loại bỏ các hiệu ứng chuyển tiếp, nó sẽ yêu cầu thay đổi giao diện và tất cả các lớp thực hiện nó.
Cá nhân tôi đã không tìm thấy mô hình này hữu ích. Bạn luôn có thể triển khai các máy trạng thái hữu hạn bằng bảng tra cứu (đây không phải là cách OO, nhưng nó hoạt động khá tốt).
Chiến lược được sử dụng cho [cuốn sách GoF p. 316] :
- nhiều lớp liên quan chỉ khác nhau trong hành vi của họ. Các chiến lược cung cấp một cách để cấu hình một lớp với một trong nhiều hành vi.
- bạn cần các biến thể khác nhau của một thuật toán. Ví dụ: bạn có thể xác định các thuật toán phản ánh sự đánh đổi không gian / thời gian khác nhau. Các chiến lược có thể được sử dụng khi các biến thể này được triển khai như một hệ thống phân cấp các thuật toán [HO87].
- một thuật toán sử dụng dữ liệu mà khách hàng không nên biết. Sử dụng mẫu Chiến lược để tránh phơi bày các cấu trúc dữ liệu cụ thể theo thuật toán.
- một lớp định nghĩa nhiều hành vi và chúng xuất hiện dưới dạng nhiều câu lệnh có điều kiện trong các hoạt động của nó. Thay vì nhiều điều kiện, hãy chuyển các nhánh có điều kiện liên quan vào lớp Chiến lược của riêng họ.
Trường hợp cuối cùng về nơi áp dụng Chiến lược có liên quan đến tái cấu trúc được gọi là Thay thế điều kiện bằng đa hình .
Tóm tắt: Nhà nước và Chiến lược giải quyết các vấn đề rất khác nhau. Nếu vấn đề của bạn không thể được mô hình hóa bằng một máy trạng thái hữu hạn, thì có khả năng mẫu Trạng thái không phù hợp. Nếu vấn đề của bạn không phải là về việc đóng gói các biến thể của một thuật toán phức tạp, thì Chiến lược sẽ không được áp dụng.
Bang có cấu trúc lớp UML sau:
Chiến lược có cấu trúc lớp UML sau:
Tóm tắt: về mặt cấu trúc tĩnh, hai mẫu này hầu hết giống hệt nhau. Trên thực tế, các công cụ phát hiện mẫu như công cụ này xem xét rằng " cấu trúc của các mẫu [...] giống hệt nhau, cấm phân biệt chúng bằng một quy trình tự động (ví dụ: không đề cập đến thông tin khái niệm). "
Tuy nhiên, có thể có một sự khác biệt lớn nếu ConcreteStates tự quyết định các chuyển đổi trạng thái (xem các liên kết " có thể xác định " trong sơ đồ trên). Điều này dẫn đến sự khớp nối giữa các trạng thái bê tông. Ví dụ (xem phần tiếp theo), trạng thái A xác định chuyển đổi sang trạng thái B. Nếu lớp Ngữ cảnh quyết định chuyển sang trạng thái cụ thể tiếp theo, các phụ thuộc này sẽ biến mất.
Như đã đề cập trong phần Vấn đề ở trên, Trạng thái ngụ ý rằng hành vi thay đổi trong thời gian chạy tùy thuộc vào trạng thái của một đối tượng. Do đó, khái niệm chuyển trạng thái được áp dụng, như đã thảo luận với mối quan hệ của máy trạng thái hữu hạn . [GoF] đề cập rằng các hiệu ứng chuyển tiếp có thể được xác định trong các lớp con ConcreteState hoặc ở một vị trí tập trung (chẳng hạn như vị trí dựa trên bảng).
Hãy giả sử một máy trạng thái hữu hạn đơn giản:
Giả sử các lớp con quyết định chuyển trạng thái (bằng cách trả về đối tượng trạng thái tiếp theo), động trông giống như thế này:
Để thể hiện tính năng động của Chiến lược , thật hữu ích khi mượn một ví dụ thực tế .
Tóm tắt : Mỗi mẫu sử dụng một cuộc gọi đa hình để làm một cái gì đó tùy thuộc vào ngữ cảnh. Trong mẫu Trạng thái, lệnh gọi đa hình (chuyển tiếp) thường gây ra thay đổi ở trạng thái tiếp theo . Trong mẫu Chiến lược, cuộc gọi đa hình thường không thay đổi ngữ cảnh (ví dụ: thanh toán bằng thẻ tín dụng một lần không có nghĩa là bạn sẽ thanh toán bằng PayPal vào lần tiếp theo). Một lần nữa, tính năng động của mẫu trạng thái được xác định bởi máy trạng thái fininte tương ứng của nó , mà (với tôi) là điều cần thiết để áp dụng đúng mẫu này.
Mẫu chiến lược liên quan đến việc di chuyển việc thực hiện thuật toán từ một lớp lưu trữ và đặt nó vào một lớp riêng biệt. Điều này có nghĩa là lớp máy chủ không cần phải cung cấp việc thực hiện từng thuật toán, điều này có khả năng dẫn đến mã ô uế.
Các thuật toán sắp xếp thường được sử dụng làm ví dụ vì tất cả chúng đều làm cùng một loại (sắp xếp). Nếu mỗi thuật toán sắp xếp khác nhau được đưa vào lớp riêng của nó, thì máy khách có thể dễ dàng chọn thuật toán nào sẽ sử dụng và mẫu cung cấp một cách dễ dàng để truy cập nó.
Mẫu trạng thái liên quan đến việc thay đổi hành vi của một đối tượng khi trạng thái của đối tượng thay đổi. Điều này có nghĩa là lớp máy chủ không cung cấp việc thực hiện hành vi cho tất cả các trạng thái khác nhau mà nó có thể có. Lớp máy chủ thường gói gọn một lớp cung cấp chức năng được yêu cầu trong một trạng thái nhất định và chuyển sang một lớp khác khi nhà nước thay đổi.
Xem xét hệ thống IVR (Phản hồi bằng giọng nói tương tác) xử lý các cuộc gọi của khách hàng. Bạn có thể muốn lập trình nó để xử lý khách hàng trên:
Để xử lý tình huống này, bạn có thể sử dụng Mẫu trạng thái .
Quá trình kết nối khách hàng với một giám đốc điều hành hỗ trợ có thể được thực hiện bằng cách sử dụng Mẫu chiến lược nơi các giám đốc điều hành được chọn dựa trên một trong hai cách sau:
Mẫu chiến lược quyết định ' cách ' thực hiện một số hành động và mẫu trạng thái quyết định ' khi nào ' để thực hiện chúng.
Chiến lược đại diện cho các đối tượng "làm" một cái gì đó, với cùng kết quả bắt đầu và kết thúc, nhưng bên trong sử dụng các phương pháp khác nhau. Theo nghĩa đó, chúng tương tự như đại diện cho việc thực hiện một động từ. Mẫu trạng thái OTOH sử dụng các đối tượng "là" một cái gì đó - trạng thái của một hoạt động. Mặc dù chúng cũng có thể đại diện cho các hoạt động trên dữ liệu đó, nhưng chúng tương tự như đại diện cho một danh từ hơn là một động từ và được điều chỉnh theo các máy trạng thái.
Chiến lược: chiến lược là cố định và thường bao gồm một số bước. (Sắp xếp chỉ cấu thành một bước và do đó là một ví dụ rất tệ vì nó quá thô sơ để hiểu mục đích của mẫu này). Thói quen "chính" của bạn trong chiến lược là gọi một vài phương thức trừu tượng. Ví dụ: "Nhập chiến lược phòng", "phương thức chính" là goThroughDoor (), trông giống như: accessDoor (), if (lock ()) openLock (); mở cửa(); enterRoom (); xoay(); đóng cửa(); if (wasLocked ()) lockDoor ();
Bây giờ các lớp con của "thuật toán" chung này để di chuyển từ phòng này sang phòng khác thông qua một cánh cửa bị khóa có thể thực hiện các bước của thuật toán.
Nói cách khác, phân lớp chiến lược không thay đổi các thuật toán cơ bản, chỉ có các bước riêng lẻ.
RATNG TRÊN là một mẫu Phương thức mẫu. Bây giờ đặt các bước thuộc về nhau (mở khóa / khóa và mở / đóng) vào các đối tượng triển khai của riêng chúng và ủy thác cho chúng. Ví dụ: khóa có khóa và khóa có thẻ mã là hai loại khóa. Đại biểu từ chiến lược đến các đối tượng "Bước". Bây giờ bạn có một mẫu Chiến lược.
Một mô hình nhà nước là một cái gì đó hoàn toàn khác nhau.
Bạn có một đối tượng gói và đối tượng bọc. Cái được bọc là "trạng thái". Đối tượng trạng thái chỉ được truy cập thông qua trình bao bọc của nó. Bây giờ bạn có thể thay đổi đối tượng được bao bọc bất cứ lúc nào, do đó trình bao bọc dường như thay đổi trạng thái của nó, hoặc thậm chí là "lớp" hoặc kiểu của nó.
Ví dụ, bạn có một đăng nhập vào dịch vụ. Nó chấp nhận tên người dùng và mật khẩu. Nó chỉ có một phương thức: đăng nhập (String userName, String passwdHash). Thay vì tự quyết định liệu đăng nhập có được chấp nhận hay không, nó ủy thác quyết định cho một đối tượng trạng thái. Đối tượng trạng thái đó thường chỉ kiểm tra xem kết hợp user / pass có hợp lệ không và thực hiện đăng nhập. Nhưng bây giờ, bạn có thể trao đổi "Trình kiểm tra" bằng cách chỉ cho phép người dùng được bảo mật đăng nhập (trong thời gian bảo trì, ví dụ) hoặc bằng cách cho phép không ai đăng nhập. Điều đó có nghĩa là "trình kiểm tra" biểu thị "trạng thái đăng nhập" của hệ thống.
Sự khác biệt quan trọng nhất là: khi bạn đã chọn một chiến lược, bạn sẽ gắn bó với nó cho đến khi bạn hoàn thành nó. Điều đó có nghĩa là bạn gọi "phương thức chính" của nó và miễn là nó đang chạy, bạn sẽ không bao giờ thay đổi chiến lược. OTOH trong tình huống mẫu trạng thái trong thời gian chạy hệ thống của bạn, bạn thay đổi trạng thái tùy ý khi bạn thấy phù hợp.
Mẫu chiến lược được sử dụng khi bạn có nhiều thuật toán cho một tác vụ cụ thể và máy khách quyết định việc triển khai thực tế sẽ được sử dụng trong thời gian chạy.
Sơ đồ UML từ bài viết mẫu Chiến lược wiki :
Các tính năng chính:
Tham khảo bài đăng này để biết thêm thông tin và ví dụ thực tế:
Ví dụ thực tế về mô hình chiến lược
Mẫu trạng thái cho phép một đối tượng thay đổi hành vi của nó khi trạng thái bên trong của nó thay đổi
Sơ đồ UML từ bài viết mẫu wiki Nhà nước:
Nếu chúng ta phải thay đổi hành vi của một đối tượng dựa trên trạng thái của nó, chúng ta có thể có một biến trạng thái trong Đối tượng và sử dụng khối điều kiện if-other để thực hiện các hành động khác nhau dựa trên trạng thái. Mô hình trạng thái được sử dụng để cung cấp một cách có hệ thống và mất kết hợp để đạt được điều này thông qua việc triển khai Bối cảnh và Nhà nước .
Tham khảo này journaldev bài viết để biết thêm chi tiết.
Khác biệt chính từ sourcemaking và journaldev bài viết:
Trong ngôn ngữ của giáo dân,
trong mẫu Chiến lược, không có trạng thái hoặc tất cả chúng có cùng trạng thái. Tất cả một người có nhiều cách khác nhau để thực hiện một nhiệm vụ, giống như các bác sĩ khác nhau điều trị cùng một bệnh của cùng một bệnh nhân với cùng một trạng thái theo những cách khác nhau.
Trong trạng thái Mẫu, chủ quan có các trạng thái, như trạng thái hiện tại của bệnh nhân (nói nhiệt độ cao hoặc nhiệt độ thấp), dựa trên đó hành động tiếp theo (đơn thuốc) sẽ được quyết định. Một trạng thái có thể dẫn đến trạng thái khác, do đó có trạng thái để phụ thuộc nhà nước (thành phần kỹ thuật).
Nếu về mặt kỹ thuật, chúng tôi cố gắng hiểu nó, dựa trên so sánh mã của cả hai, chúng tôi có thể mất tính chủ quan của tình huống, bởi vì cả hai đều trông rất giống nhau.
Cả hai mẫu đều ủy quyền cho một lớp cơ sở có một số đạo hàm, nhưng chỉ trong mẫu Trạng thái mà các lớp phái sinh này giữ một tham chiếu trở lại lớp ngữ cảnh.
Một cách khác để xem xét đó là mẫu Chiến lược là phiên bản đơn giản hơn của mẫu Trạng thái; một mẫu phụ, nếu bạn thích. Nó thực sự phụ thuộc vào việc bạn có muốn các trạng thái dẫn xuất giữ các tham chiếu trở lại bối cảnh hay không (tức là: bạn có muốn chúng gọi các phương thức trên ngữ cảnh không).
Để biết thêm thông tin: Robert C Martin (& Micah Martin) trả lời điều này trong cuốn sách của họ, "Nguyên tắc, mô hình và thực tiễn Agile trong C #". ( http://www.amazon.com/Agile-Principles-Potypes-Practices-C/dp/0131857258 )
Đây là một câu hỏi khá cũ, nhưng, tôi cũng đang tìm kiếm câu trả lời tương tự và đây là những gì tôi đã khám phá ra.
Đối với mẫu Trạng thái, hãy xem xét một ví dụ về nút Phát Medial Player. Khi chúng tôi chơi, nó bắt đầu chơi và làm cho bối cảnh nhận ra rằng nó đang chơi. Mỗi khi khách hàng muốn thực hiện thao tác chơi, anh ta sẽ kiểm tra trạng thái hiện tại của người chơi. Bây giờ khách hàng biết trạng thái của đối tượng đang phát thông qua đối tượng bối cảnh nên anh ta gọi phương thức hành động của đối tượng trạng thái tạm dừng. Một phần của khách hàng nhận ra trạng thái và trạng thái cần thực hiện hành động có thể được tự động hóa.
https://www.youtube.com/watch?v=e45RMc76884 https://www.tutorialspoint.com/design_potype/state_potype.htmlm
Trong trường hợp mẫu Chiến lược, việc sắp xếp sơ đồ lớp giống như mẫu trạng thái. Khách hàng đến sự sắp xếp này để thực hiện một số thao tác. Đó là thay vì các trạng thái khác nhau, có các thuật toán khác nhau nói ví dụ phân tích khác nhau cần được thực hiện trên mẫu. Ở đây, khách hàng nói với bối cảnh những gì nó muốn làm đó là thuật toán nào (thuật toán tùy chỉnh do doanh nghiệp xác định) và sau đó thực hiện điều đó.
https://www.tutorialspoint.com/design_potype/strargety_potype.htmlm
Cả hai đều thực hiện nguyên tắc đóng mở để nhà phát triển có khả năng thêm các trạng thái mới vào mẫu trạng thái và thuật toán mới.
Nhưng sự khác biệt là những gì chúng được sử dụng là mẫu trạng thái được sử dụng để thực thi logic khác nhau dựa trên trạng thái của đối tượng. Và trong một trường hợp chiến lược logic khác nhau.
Trạng thái đi kèm với một chút phụ thuộc trong các lớp dẫn xuất trạng thái: giống như một trạng thái biết về các trạng thái khác xuất hiện sau nó. Ví dụ: Mùa hè đến sau mùa đông cho bất kỳ trạng thái mùa nào hoặc trạng thái Giao hàng sau trạng thái Gửi tiền để mua sắm.
Mặt khác, Chiến lược không có sự phụ thuộc như thế này. Ở đây, bất kỳ loại trạng thái nào cũng có thể được khởi tạo dựa trên loại chương trình / sản phẩm.
Sự khác biệt được thảo luận trong http://c2.com/cgi/wiki?StrargetyPotype . Tôi đã sử dụng mẫu Chiến lược để cho phép các thuật toán khác nhau được chọn trong khuôn khổ tổng thể để phân tích dữ liệu. Thông qua đó bạn có thể thêm các thuật toán mà không phải thay đổi các khung tổng thể và logic của nó.
Một ví dụ điển hình là bạn amy có một khung để tối ưu hóa một chức năng. Khung thiết lập dữ liệu và tham số. Mẫu chiến lược cho phép bạn chọn các thuật toán như phần tử gốc, độ dốc liên hợp, BFGS, v.v. mà không làm thay đổi khung.
Cả mô hình Chiến lược và Nhà nước có cùng cấu trúc. Nếu bạn nhìn vào sơ đồ lớp UML cho cả hai mẫu chúng trông giống hệt nhau, nhưng ý định của chúng là hoàn toàn khác nhau. Mẫu thiết kế trạng thái được sử dụng để xác định và quản lý trạng thái của một đối tượng, trong khi mẫu Chiến lược được sử dụng để xác định một bộ thuật toán có thể hoán đổi cho nhau và cho phép khách hàng chọn một trong số chúng. Vì vậy, mẫu Chiến lược là một mẫu do khách hàng điều khiển trong khi Object có thể tự quản lý trạng thái đó.
Khi bạn có một dự án có thể được chia thành 2 nhiệm vụ:
nhiệm vụ 1: bạn có thể sử dụng một trong hai thuật toán khác nhau để thực hiện: alg1, alg2
nhiệm vụ 2: bạn có thể sử dụng một trong ba thuật toán khác nhau để thực hiện: alg3, alg4, alg5
alg1 và alg2 có thể hoán đổi cho nhau; alg3, alg4 và alg5 có thể hoán đổi cho nhau.
Việc chọn thuật toán nào để thực hiện trong nhiệm vụ 1 và nhiệm vụ 2 phụ thuộc vào các trạng thái:
trạng thái 1: bạn cần alg1 trong nhiệm vụ 1 và alg3 trong nhiệm vụ 2
trạng thái 2: bạn cần alg2 trong nhiệm vụ 1 và alg5 trong nhiệm vụ 2
Ngữ cảnh của bạn có thể thay đổi đối tượng trạng thái từ trạng thái 1 sang trạng thái 2. Sau đó, nhiệm vụ của bạn sẽ được hoàn thành bởi alg2 và alg5, thay vì alg1 và alg3.
Bạn có thể thêm nhiều thuật toán có thể hoán đổi cho nhiệm vụ 1 hoặc nhiệm vụ 2. Đây là mẫu chiến lược.
Bạn có thể có nhiều trạng thái hơn với sự kết hợp các thuật toán khác nhau trong nhiệm vụ 1 và nhiệm vụ 2. Mẫu trạng thái cho phép bạn chuyển từ trạng thái này sang trạng thái khác và thực hiện kết hợp các thuật toán khác nhau.
"Chiến lược" chỉ là một thuật toán mà bạn có thể thay đổi nó trong các trường hợp khác nhau theo nhu cầu của bạn và nó xử lý một cái gì đó cho bạn. Ví dụ. bạn có thể chọn cách nén một tập tin. zip hoặc rar ... trong một phương thức.
Nhưng 'Trạng thái' CÓ THỂ thay đổi tất cả hành vi đối tượng của bạn, khi nó thay đổi, Thậm chí nó có thể thay đổi các trường khác ... đó là lý do tại sao nó có tham chiếu đến chủ sở hữu của nó. Bạn nên chú ý rằng việc thay đổi một trường đối tượng có thể thay đổi hành vi của đối tượng. Ví dụ. Khi bạn thay đổi State0 thành State1 trong obj, bạn thay đổi một số nguyên thành 10 .. vì vậy khi chúng ta gọi obj.f0 () thực hiện một số phép tính và sử dụng số nguyên đó, nó sẽ ảnh hưởng đến kết quả.