Có một mẫu thiết kế sẽ áp dụng cho các mô hình giảm giá?


35

Có bất kỳ mẫu thiết kế được biết đến để thực hiện các mô hình giảm giá?

Theo mô hình giảm giá, tôi có nghĩa là sau đây:

  1. Nếu khách hàng mua Sản phẩm X, Sản phẩm Y và Sản phẩm Z, anh ta được giảm giá 10% hoặc 100 đô la.

  2. Nếu một khách hàng mua 100 đơn vị Sản phẩm X, anh ta được giảm giá 15% hoặc 500 đô la

  3. Nếu một khách hàng đã mang về năm ngoái hơn 100 nghìn đô la, anh ta sẽ được giảm giá 20%

  4. Nếu một khách hàng đã mua 2 đơn vị Sản phẩm X, anh ta sẽ được miễn phí 1 đơn vị Sản phẩm X (hoặc Sản phẩm Y).

  5. ...

Có một mô hình chung có thể được áp dụng để xử lý tất cả các tình huống trên không? Tôi đang nghĩ về một vài mô hình, nhưng không thể bắt gặp một mô hình chung chung.


IIRC tất cả các hướng dẫn tôi đã thấy với các ví dụ liên quan đến giảm giá (có rất nhiều) đề xuất mẫu Chiến lược
gnat

2
@Kanini Đây có phải là một vấn đề trong thế giới thực? Trong trường hợp như vậy là hệ thống này trong thời gian thực hoặc thời gian hoãn lại? Các quy tắc này được trình bày dưới dạng công cụ quy tắc hay giá trị cơ sở dữ liệu? Là tìm kiếm giảm giá phân cấp dựa trên ưu tiên? Mô hình chiến lược sẽ hoạt động trong hầu hết các trường hợp nhưng các quy tắc của bạn phải được thực hiện để làm cho nó hoạt động
Ubermensch

3
Ngoài ra, nếu ai đó mua 2 đơn vị Sản phẩm X, một Sản phẩm Y và một Sản phẩm Z, sẽ nhận được cả 10% và một sản phẩm X bổ sung?
Ubermensch

@gnat một số liên kết đến một số hướng dẫn xin vui lòng.
dùng16764

Câu trả lời:


18

Nếu vấn đề là bạn cần áp dụng nhiều chiết khấu, trong các trường hợp cụ thể, bạn có thể muốn xem xét mẫu Chuỗi trách nhiệm .

Tóm lại, bạn chuyển thông tin bạn muốn xử lý vào bộ xử lý đầu tiên và nó quyết định từ đó có chuyển nó cho bộ xử lý tiếp theo hay không trước khi trả về kết quả.

Bằng cách này, bạn có thể thay đổi cấu trúc và trình tự của bộ xử lý mà không bao giờ thay đổi mã gọi.


Chuỗi trách nhiệm là một trong những tốt. Thậm chí có thể được kết hợp với một chiến lược. Trong trường hợp chỉ có thể áp dụng một mức giảm giá, mỗi chiến lược được kết nối với nhau. Mỗi chuỗi tính toán mức chiết khấu của nó (nếu khách hàng đủ điều kiện), so sánh với mức giảm giá trước đó và chuyển dữ liệu của khách hàng, đặt hàng và chiết khấu cho chuỗi tiếp theo. +1.
Thomas Owens

1
Chỉ là ý kiến ​​của tôi, nhưng tôi thấy nhiều khả năng "Chuỗi trách nhiệm" được thiết kế quá mức cho trường hợp này. Một danh sách đơn giản các mô hình giảm giá (nếu cần, với một số thứ tự) nên làm điều đó. Danh sách này là độc lập với khách hàng và đơn đặt hàng của mình, vì tất cả các khách hàng sẽ được đối xử bình đẳng. "Chuỗi phản hồi" phù hợp hơn khi danh sách mô hình giảm giá thay đổi rất thường xuyên vào thời gian chạy theo cách rất năng động.
Doc Brown

11

Các mô hình Chiến lược, Trang trí và Nhà nước nổi bật với tôi như là điểm khởi đầu tiềm năng. Trạng thái có thể đặc biệt hữu ích cho 2 hoặc 3, vì 2 phụ thuộc vào trạng thái của đơn đặt hàng và 3 phụ thuộc vào trạng thái của khách hàng trong một khoảng thời gian. Chiến lược và Nhà trang trí nổi bật so với các chiến lược khác, vì bạn có thể sử dụng chiến lược để thực hiện nhiều thuật toán tính toán giá và đơn hàng trang trí để thêm giảm giá mới cho đơn hàng.

Tuy nhiên, hãy nhớ rằng các mẫu thiết kế chỉ là mô hình. Có thể không có một mẫu nào được áp dụng, mà là một hệ thống các mẫu. Cũng xem xét việc sửa đổi các mô hình được mô tả để làm cho chúng phù hợp hơn với giải pháp của bạn. Tốt hơn là nên có một thiết kế tốt hơn là ép buộc một mẫu mà nó không nhất thiết phải giúp chỉ vì có thể nói bạn có một mẫu.


Đó thực sự không phải là những gì mô hình nhà nước dự định làm, phải không?
pdr

@pdr Tôi không thấy tại sao không. Nhưng nó phụ thuộc vào việc thực hiện của bạn. Nếu đối tượng khách hàng của bạn theo dõi các khoản giảm giá phụ thuộc vào khách hàng, thì có thể có một hoạt động để trả lại các khoản giảm giá mà khách hàng đủ điều kiện nhận. Khi khách hàng mua đồ, các thuộc tính thay đổi và phương thức thực hiện này thay đổi thông qua mẫu trạng thái.
Thomas Owens

1
Hmm, tôi hiểu ý của bạn. Tôi nghĩ rằng nó phụ thuộc nếu khách hàng là một đối tượng bán cố định trong ứng dụng, hoặc chỉ là một cái gì đó sống trong cơ sở dữ liệu và cần cập nhật. Nó không rõ ràng từ câu hỏi, đủ công bằng. +1
pdr

3
Từ kinh nghiệm của tôi, các loại quy tắc kinh doanh giảm giá này luôn được sửa đổi bởi các bộ phận tiếp thị / bán hàng hay thay đổi. Có một nhu cầu lớn để làm cho chúng điều khiển dữ liệu và người dùng có thể sửa đổi thay vì điều khiển hoàn toàn bằng mã. Làm thế nào điều này sẽ ảnh hưởng đến sự lựa chọn của mô hình?
jfrankcarr

@jfrankcarr Trong suy nghĩ của tôi, nó sẽ không. Tôi sẽ đưa ra các giá trị cho các bộ vật phẩm dẫn đến giảm giá, giảm phần trăm và v.v. từ một số loại cấu hình. Sắp xếp một cách linh hoạt việc chuyển đổi máy trạng thái và các thuộc tính của các nhà trang trí và chiến lược của tôi.
Thomas Owens

10

Chà, tôi sẽ thiết kế một mô hình giảm giá như một cặp "Điều kiện tiên quyết" và "Giảm giá", trong đó "Điều kiện tiên quyết" là một lớp với các phương thức

  bool IsFulfilled(Customer c);

hoặc và

  bool IsFulfilled(Customer c, Order o);

và Giảm giá có một phương pháp void ApplyTo(Customer c). Điều này cung cấp cho bạn khả năng kết hợp bất kỳ loại tiền điều kiện nào với bất kỳ loại giảm giá nào (tôi nghĩ đây là một dạng "mẫu cầu").

Nếu bạn có một số điều kiện tiên quyết cố định, thì bạn có thể giải quyết vấn đề bằng cách xây dựng các kiểu con cụ thể (mẫu chiến lược). Tuy nhiên, khi các điều kiện tiên quyết của bạn được cho phép rất phức tạp, với các câu lệnh logic như AND, OR và NOT, bạn có thể thực hiện tốt hơn một số loại trình thông dịch quy tắc cho các điều kiện. Các quy tắc có thể là một chuỗi văn bản đơn giản được viết bằng một "ngôn ngữ cụ thể miền" đơn giản.

Điều tương tự cũng xảy ra với lớp "Giảm giá", bạn có thể có một số kiểu con cho các loại giảm giá khác nhau hoặc cách tiếp cận chung trong đó các quy tắc giảm giá được đưa ra dưới dạng văn bản, được đánh giá bởi một số thông dịch viên.


Trực giác của tôi cho thấy đây có thể là những gì anh ta đang tìm kiếm trong bối cảnh của câu hỏi
Ubermensch

4
  • Có lẽ cần một giao diện IDiscount vì tất cả các giảm giá khác nhau là như nhau, và chúng tôi sẽ muốn đối phó với chúng về mặt khái niệm là giảm giá chung.

  • Lớp "đặt hàng của khách hàng này" có lẽ cần một bộ Giảm giá. Danh sách? Băm? Danh sách liên kết? Đừng quan tâm, chưa. Giảm giá áp dụng cho mua hàng, không phải khách hàng!

  • Giữ tòa nhà Giảm giá tách biệt với Khách hàng, Giỏ hàng, Lịch sử, v.v ... Nó sẽ thay đổi rất nhiều - như @jfrankcarr đã chỉ ra.

  • Có lẽ là một lớp khác nhau cho mỗi lần giảm giá vì thuật toán và tham số cho mỗi lần giảm giá khác nhau một cách dữ dội và không thể đoán trước.

  • Tôi thấy rất nhiều sự kiện xử lý khi tính toán chiết khấu đáp ứng với thay đổi giỏ hàng và ngược lại.

Thiết kế mẫu ứng dụng

  • Tôi thấy a strategy pattern. IDiscount là giao diện để thực hiện các thuật toán giảm giá khác nhau.
  • Tôi thấy a factory. Chắc chắn không phải là một toàn diện abstract factory pattern, mà là một lớp duy nhất tại thời điểm này trong phân tích. Một cách hợp lý, phải có một nơi duy nhất có đủ bối cảnh để quyết định áp dụng giảm giá nào và sau đó tạo ra chúng. Một lớp. Nếu các quy tắc áp dụng giảm giá sau đó bùng nổ do một bữa tiệc nấm của Phòng Tiếp thị, bất kỳ logic Xây dựng Giảm giá bổ sung nào vẫn phải kết hợp trong lớp nhà máy cơ sở này, tôi nghĩ.

  • Tôi có thể thấy Chain of Responsibility. Đây không phải là loại trừ lẫn nhau cho factoryý tưởng. Thay vì lặp đi lặp lại một bộ sưu tập giảm giá, mỗi lần giảm giá sẽ gọi anh chàng tiếp theo. Lớp "đặt hàng của khách hàng" không tổ chức một bộ sưu tập giảm giá trong trường hợp này.

  • Yếu tố "hmmmm ...." trong Chuỗi trách nhiệm, tôi nghĩ, là mỗi Giảm giá có một tham chiếu đến tiếp theo. Hàm ý là vấn đề trật tự. Đó không phải là trường hợp. Ngoài ra, khái niệm CoR thể hiện là một đối tượng không thể xử lý yêu cầu để nó được chuyển "lên cấp cao hơn tiếp theo". Mô hình của chúng tôi là khác nhau. Yêu cầu duy nhất là tính toán. Mỗi giảm giá làm điều này. Đầu ra hoặc hiệu ứng có thể là null nhưng mọi chiết khấu đều tính toán. Tôi theo bản năng nghiêng về một sự trung thực trong thế giới thực cao hơn.

Giả định

  • Giảm giá dựa trên giỏ hàng hiện tại và / hoặc lịch sử mua hàng
  • Không hoặc giảm giá nhiều hơn có thể được áp dụng. Không có giảm giá loại trừ lẫn nhau
  • Tính toán thích hợp không phụ thuộc vào thứ tự giảm giá được áp dụng.

Những gì thay đổi, những gì vẫn giữ nguyên?

  • Giảm giá rất khác nhau. Số lượng và loại tham số khác nhau để tạo nên mỗi quy tắc.

  • Đối số cho giảm giá đủ điều kiện thay đổi khi giỏ hàng thay đổi.

  • Số lượng giảm giá thay đổi có sẵn

  • Giảm giá khách hàng này đủ điều kiện để thay đổi khi giỏ hàng của mình thay đổi.

  • Lịch sử mua sắm không thay đổi trong bối cảnh mua hàng này

  • Tổng chi phí thay đổi linh hoạt như một chức năng của các dòng mua hàng và giảm giá được áp dụng.

  • Sau khi ứng dụng ban đầu, sản lượng giảm giá có thể thay đổi, chẳng hạn như số lượng mua thay đổi.


Câu trả lời tuyệt vời và đầy đủ ... NHƯNG tôi chỉ có một mối quan tâm và là phần giả định không nên ở đó, ít nhất là không dẫn dắt câu trả lời. Toàn bộ ý tưởng là mô hình giúp đưa ra chính xác và quên đi các "giả định", quy tắc chung không cần biết về cách tính toán được thực hiện và bất kỳ triển khai chi tiết nào sử dụng từ ngữ cảnh (Các mục của Khách hàng, Giỏ hàng , Ngày giờ, Mùa, vân vân). Thực sự giúp đầy đủ mặc dù
le0diaz

Các gạch đầu dòng phía trước và phần 'Giả định' chỉ là lý do "thể hiện công việc của bạn" về vấn đề của chính nó, tất nhiên có một mâu thuẫn trong thiết kế mô hình giảm giá. Ví dụ, các giả định của tôi về thứ tự thực hiện giảm giá và sự phụ thuộc lẫn nhau khiến tôi không nhấn mạnh đến Chuỗi trách nhiệm. Lưu ý rằng tôi đang suy nghĩ về ý định của mô hình, chứ không phải sự phức tạp như @docbrown. Tôi là một người ủng hộ nhiệt tình cho việc phản ánh ý định trong thiết kế.
radarbob

1

Theo logic, một mô hình giảm giá có thể là bất cứ điều gì , vì vậy bạn không thể cho rằng bạn có thể lập trình trước tất cả các trường hợp. Cũng không ai có thể trả lời câu hỏi của bạn hoàn toàn chắc chắn những gì bạn thực sự cần. Tuy nhiên, giả sử bạn nhận được các loại giảm giá thông thường được tìm thấy trong thế giới thực ...

Một câu hỏi lớn là liệu giảm giá sẽ được lập trình, hoặc nếu bạn muốn người dùng nhập chúng. Như đã đề cập ở trên, bạn không bao giờ có thể lập trình chúng, nhưng thông thường mục tiêu là cố gắng làm cho nó nhập dữ liệu nhiều hơn như đối với các trường hợp thông thường, thay vì lập trình tất cả. Điều này áp dụng cho một số mức độ ngay cả khi các lập trình viên được sử dụng để tạo ra tất cả các giảm giá.

Martin Fowler đề cập đến "Phương pháp cá nhân" trong "Các mẫu phân tích: mô hình đối tượng có thể tái sử dụng" như là một phần của cách triển khai "Quy tắc gửi bài" cho các hệ thống kế toán, nhưng các quy tắc có vẻ khá giống với bạn. Tôi sẽ cung cấp thêm chi tiết nhưng đó là một tác phẩm có bản quyền và

Đối với giao diện người dùng, bạn cần phải đưa ra các trường hợp sử dụng khá đơn giản hoặc người nào khác xây dựng trình thông dịch và trình tạo truy vấn. Có thể cả hai, một cho các trường hợp đơn giản và một nâng cao hơn. Nếu bạn viết một trình thông dịch, thì đây có thể là một trường hợp khá tốt để sử dụng mẫu Phiên dịch, vì mã tương đối đơn giản so với trình tạo trình phân tích cú pháp và thời gian phân tích chậm hơn có lẽ sẽ không thực sự quan trọng. (Nếu bạn thích sử dụng trình tạo phân tích cú pháp, đừng để tôi ngăn bạn).

Mặc dù vậy, đừng cố gắng làm mọi thứ với một thông dịch viên - tại một số điểm bạn chỉ đang lập trình bằng ngôn ngữ nhàu nát của chính mình, vì vậy bạn cũng có thể sử dụng một trình thông dịch thực sự. Nếu ngôn ngữ được giải thích của bạn hỗ trợ các chức năng (có lẽ nên hỗ trợ gọi chúng - xác định chúng là không rõ ràng) những ngôn ngữ đó có thể được mã hóa bằng ngôn ngữ thực. Đừng đi xa hơn con đường này hơn bạn phải đi.

Bất kể bạn làm gì, cuối cùng cũng có người muốn giảm giá dựa trên việc họ đã mua trong vòng 30 ngày làm việc của chương trình khuyến mãi - trong đó ngày làm việc chỉ được tính nếu không có ngày nghỉ trong khu vực được xác định bởi mã bưu chính của cửa hàng hoặc của khách hàng mã bưu điện. Vì vậy, đừng cố gắng thiết kế hệ thống hoàn hảo trước - giả sử đôi khi bạn sẽ cần phải viết mã cho các loại giảm giá mới và thiết kế phù hợp.


0

Có bất kỳ điểm nào được hỏi nếu có một mô hình hữu ích cho việc này? Những loại mô hình được yêu cầu - cấu trúc hoặc hành vi?

Lý tưởng nhất, nếu tôi định viết một phần mềm cho việc này, tất cả những gì nó cần là một thuật toán . Một hàm đơn giản tính tổng chiết khấu như sau:

cart.calculateDiscount(productVector);

Bạn không cần nhiều thứ hơn thế này!

Để làm rõ: Tôi hiểu rằng sẽ có nhiều quy tắc - cơ bản nhất của biểu diễn đó phải ở dạng cơ sở quy tắc (tập hợp các thuộc tính dữ liệu và chiết khấu kết quả đối với nó) và hàm như trên sẽ lặp lại để tính toán nó. Nếu quy tắc được thêm hoặc xóa, bạn không nên thay đổi mã - chỉ cần thay đổi cơ sở quy tắc.

Mẫu sẽ chỉ được yêu cầu nếu chúng ta cần các đối tượng khác nhau để truy cập API của nhau hoặc liên lạc để đặt một nhiệm vụ.

PS: Hãy nghĩ về nó - khi tường lửa xử lý các gói và vượt qua hoặc từ chối các gói (hoặc sửa đổi nó) - nó sử dụng mẫu thiết kế nào? Câu trả lời là KHÔNG của các mô tả ở trên!


Tất nhiên bạn cần nhiều hơn thế !!! Ý tưởng là thuật toán không được kết hợp chặt chẽ với việc thực thi mã. Nếu bạn kiểm tra các kịch bản có khả năng cao sẽ xuất hiện nhiều kịch bản hơn, thì bạn cũng đã đề cập đến nó bằng cách nào đó, anh ta thực sự không biết bất kỳ 'Quy tắc' nào khác sẽ phụ thuộc vào. Thật ngây thơ khi nghĩ rằng một quy tắc sẽ chỉ phụ thuộc vào danh sách sản phẩm, nhưng trong thực tế phụ thuộc vào khách hàng, thời gian, mùa và vân vân. Không biết bạn đã kiểm tra triển khai Tường lửa nào, nhưng những cái tôi đã kiểm tra CÓ CÓ nhiều mẫu cấu trúc / thiết kế
le0diaz
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.