Ẩn / tắt tính năng cho một số người dùng


10

Hãy nói rằng tôi có một phiên bản miễn phí và trả phí của ứng dụng. Phiên bản trả phí là một siêu phiên bản miễn phí liên quan đến các tính năng có sẵn cho người dùng, có nghĩa là phiên bản trả phí sẽ có tất cả các tính năng của ứng dụng miễn phí cộng thêm.

Có một mẫu để chuyển đổi tính khả dụng dựa trên cờ tải khi khởi động (ví dụ: miễn phí / trả phí) không?

Tôi không thích ý tưởng có các khối mã theo sau ở mọi nơi:

if(isFreeVersion){
    // ...
} else {
    // ...
}

Có 2 nhánh git riêng cho mỗi phiên bản không phải là một tùy chọn vì điều đó có nghĩa là duy trì 2 (hoặc nhiều hơn) nguồn mã, nói chung có vẻ không thực tế và được thảo luận thêm ở đây: Duy trì hai phiên bản phần mềm riêng biệt từ cùng một Codebase trong Kiểm soát phiên bản .

Có cách nào để làm điều này không, trong khi vẫn có một cơ sở mã duy nhất và không xả rác mã với các câu lệnh có điều kiện kiểm tra cờ miễn phí / trả phí?

Tôi chắc chắn rằng điều này đã được thảo luận nhiều lần trước đây và tôi chắc chắn có một số mô hình để tiếp cận vấn đề này, nhưng tôi không thể tìm thấy nó.

Chúng tôi sử dụng Android / Java.



@gnat tnx, tìm đẹp. Nhưng tôi muốn thảo luận về các tùy chọn không yêu cầu các nhánh riêng biệt và duy trì nhiều cơ sở mã
Tadija Bagarić

2
Điều này trông tương tự như có các cấp ủy quyền khác nhau. Bạn có thể xem xét vấn đề đó thường được giải quyết như thế nào, trong đó một tính năng chỉ khả dụng cho một số người dùng / vai trò nhất định.
Bart van Ingen Schenau

@BartvanIngenSchenau Tôi thấy nó chủ yếu là ifkiểm tra để ẩn các điều khiển cho các tính năng bị cấm hoặc có hộp thoại bật lên khi người dùng cố gắng làm những gì anh ta không được phép. Tôi hy vọng tìm ra cách để tránh nhiều điều kiện trong mã
Tadija Bagarić

2
Sử dụng đa hình. Bạn sẽ không bao giờ phải tự hỏi về điều này nếu tuyên bố một lần nữa, và nó sẽ dễ dàng hơn rất nhiều để duy trì!
Steve Chamaillard

Câu trả lời:


14

Một like có điều kiện if(isFreeVersion)nên xảy ra chỉ một lần trong mã. Đây không phải là một mẫu, nhưng tôi chắc chắn bạn đã biết tên của nó: nó được gọi là nguyên tắc DRY . Có mã như " if(isFreeVersion)" ở nhiều nơi trong mã của bạn nghĩa là bạn đã lặp lại dòng này / logic trong đó, điều đó có nghĩa là nó phải được cấu trúc lại để tránh sự lặp lại.

" if(isFreeVersion)" nên được sử dụng để thiết lập danh sách các tùy chọn cấu hình bên trong cho các tính năng khác nhau. Mã kết quả sau đó có thể trông như thế này:

 if(isFreeVersion)
 {
      feature1Enabled=false;
      feature2Enabled=false;
      maxNoOfItems=5;
      advertisingStrategy=new ShowLotsOfAdvertisementsStrategy();
      // ...
 } 
 else
 {
      feature1Enabled=true;
      feature2Enabled=true;
      maxNoOfItems=int.MaxValue; // virtually unlimited
      advertisingStrategy=new ShowMinimalAdvertisementsStrategy();
 }

Điều này ánh xạ cờ "isFreeVersion" duy nhất của bạn sang các tính năng khác nhau . Lưu ý bạn có thể quyết định ở đây nếu bạn thích sử dụng các cờ boolean riêng cho các tính năng riêng lẻ hoặc sử dụng một số loại tham số khác, ví dụ như các đối tượng chiến lược khác nhau có giao diện chung, nếu điều khiển tính năng yêu cầu tham số phức tạp hơn.

Bây giờ bạn có quyền kiểm soát những gì trong phiên bản miễn phí và những gì trong phiên bản trả tiền ở một nơi, điều này giúp cho việc bảo trì logic này khá đơn giản. Bạn vẫn sẽ phải cẩn thận vì không làm cho mã của mình bị lộn xộn với nhiều if(feature1Enabled)câu lệnh (bằng cách tuân theo nguyên tắc DRY), nhưng bây giờ việc bảo trì kiểm tra này không còn đau đớn nữa. Ví dụ: bạn có quyền kiểm soát tốt hơn nhiều về những gì bạn cần thay đổi khi bạn muốn làm cho một tính năng trả phí hiện có miễn phí (hoặc ngược lại).

Cuối cùng, chúng ta hãy xem bài viết trên blog của Fowler về các tính năng chuyển đổi , nơi anh ấy nói về các điểm nhập cảnh / điểm chuyển đổi tính năng. Hãy để tôi trích dẫn một điểm trung tâm:

Đừng cố gắng bảo vệ mọi đường dẫn mã trong mã tính năng mới bằng cách chuyển đổi, chỉ tập trung vào các điểm nhập sẽ dẫn người dùng đến đó và chuyển đổi các điểm nhập đó.

Vì vậy, như một chiến lược tổng thể, hãy tập trung vào giao diện người dùng và hạn chế kiểm tra của bạn ở số điểm tối thiểu cần có để làm cho một tính năng nhất định xuất hiện hoặc biến mất. Điều đó sẽ giữ cho cơ sở mã của bạn sạch sẽ, không có sự lộn xộn không cần thiết.


5
Về cơ bản, bạn đã thay thế IsFreeVersion bằng FeaturexEnables, bạn đã không giảm số lượng cuộc gọi. Mặc dù tôi không có chính xác trường hợp đó, tôi luôn xử lý những thứ tương tự bằng cách tạo menu vô hiệu hóa những tùy chọn mà người dùng không nên thấy. Chủ yếu đây là lúc tạo biểu mẫu nhưng đôi khi tôi đã phải làm điều đó khi chuẩn bị một menu bật lên.
Loren Pechtel

1
@LorenPechtel: bạn nên đọc lại câu trả lời của tôi, cẩn thận hơn. Tôi thực sự đã đề cập đến hai điều để giảm số lượng bài kiểm tra có điều kiện, một trong số đó là nguyên tắc DRY, một trong số đó tập trung vào các bài kiểm tra trong UI. Quan trọng hơn, việc lập bản đồ một lá cờ không đặc hiệu như isFreeVersionđể cụ thể các thông số tính năng loại bỏ hầu hết nỗi đau của những bài kiểm tra - họ sẽ thực sự bắt đầu có ý nghĩa và không tạo ra một mớ hỗn độn bảo trì nữa.
Doc Brown

9

Nếu bạn không thích if/elsecác khối, thì bạn có thể cấu trúc lại chúng để sử dụng tính kế thừa (xem Thay thế điều kiện bằng đa hình từ cuốn sách Tái cấu trúc của Marin Fowler ). Cái này sẽ:

  • Làm cho nó đơn giản hơn một chút để lý do về mã của bạn.

  • Làm cho có thể có hai lớp, một cho phiên bản miễn phí và một cho phiên bản trả phí, lần lượt gửi các cuộc gọi đến các lớp khác, đảm bảo rằng sự khác biệt giữa phiên bản miễn phí và trả phí được giới hạn ở hai lớp (ba tính lớp cơ sở).

  • Sau này, làm cho nó dễ dàng hơn để thêm các dạng phần mềm khác của bạn, chẳng hạn như một biến thể giá rẻ hoặc phiên bản cao cấp. Bạn sẽ chỉ cần thêm một lớp khác và khai báo nó một lần trong mã của mình và bạn sẽ biết toàn bộ cơ sở mã sẽ vẫn hoạt động như mong đợi.


3
Tôi nghĩ rằng bạn có thể muốn rõ ràng hơn rằng kế thừa thực hiện là không cần thiết cho việc này. Một lợi ích khác là ứng dụng miễn phí có thể được cung cấp mà không có các tính năng cao cấp. Sửa đổi mã byte Java để làm cho một điều kiện if luôn luôn đúng không quá khó.
JimmyJames

6

Dường như với tôi câu hỏi của bạn có thể được giải quyết khá tốt khi áp dụng Mô hình Chuyển đổi Tính năng .

Như thường lệ, Pete Hodgson đã giải thích trong một bài viết tất cả các kịch bản bạn có thể phải đối mặt khi áp dụng mô hình này, tốt hơn nhiều mà tôi có thể làm.

Ngoài ra còn có một số thư viện hỗ trợ mẫu này. Tôi đã có kinh nghiệm làm việc với FF4J trong Java nhưng tôi sẽ đoán nếu bạn gõ:

feature toggle <whatever language you prefer>

... Trong bất kỳ công cụ tìm kiếm nào, bạn sẽ nhận được một số giải pháp.


1

Có nhiều hơn một cách để thực hiện điều này. Cách đơn giản và dễ hiểu là sử dụng Mẫu Chuyển đổi tính năng được cung cấp trong rất nhiều bài viết. Cách tiếp cận tiếp theo phải làm với việc thiết kế các tính năng có thể cắm. Cả Android và IOS đều có thanh toán trong ứng dụng. Cùng với đó là khả năng tải xuống.

Khi bạn xem các Servlets, JAME Mailets và thậm chí cả các plugin IDE, tất cả chúng đều sử dụng khái niệm về kiến ​​trúc trình cắm:

  • Xác định giao diện mà ứng dụng của bạn biết cách sử dụng. Giao diện đó cần cung cấp một cách để đưa chính nó vào điều hướng của ứng dụng của bạn và bất kỳ ứng dụng nào khác để bổ sung các điểm tiếp xúc.
  • Thiết lập đường dẫn mà ứng dụng của bạn sẽ đọc khi khởi động (quản lý plugin thời gian chạy khó khăn hơn rất nhiều)
  • Nếu một plugin tồn tại (như tệp Java Jar), ​​ứng dụng sẽ đọc tệp kê khai để tìm cách triển khai giao diện plugin hoặc quét một lớp thực hiện giao diện.
  • Khi lớp đó được tìm thấy, nó được khởi tạo và các phương thức thích hợp được gọi để tích hợp các tính năng mới.

Điều này cũng cho phép bạn là cơ hội để có các lớp tính năng khác nhau có sẵn cho các đối tượng khác nhau. Người dùng chỉ có các tính năng họ trả tiền.

Mã ứng dụng của bạn được duy trì dưới dạng một cơ sở mã và trình cắm của bạn là một cơ sở mã riêng - nhưng chỉ bao gồm các phần có liên quan đến plugin. Ứng dụng biết cách xử lý các plugin khi chúng có mặt và plugin chỉ biết cách tương tác với giao diện.

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.