Xử lý các giao diện tính năng


10

Gần đây tôi đã chứng kiến ​​ngày càng nhiều vấn đề tương tự như những vấn đề được giải thích trong bài viết này về các giao điểm tính năng. Một thuật ngữ khác cho nó sẽ là các dòng sản phẩm, mặc dù tôi có xu hướng gán những thứ này cho các sản phẩm thực sự khác nhau, trong khi tôi thường gặp phải những vấn đề này dưới dạng cấu hình sản phẩm có thể.

Ý tưởng cơ bản của loại vấn đề này rất đơn giản: Bạn thêm một tính năng vào sản phẩm, nhưng bằng cách nào đó mọi thứ trở nên phức tạp do sự kết hợp của các tính năng hiện có khác. Cuối cùng, QA tìm thấy một vấn đề với sự kết hợp các tính năng hiếm hoi mà không ai nghĩ đến trước đây và những gì đáng lẽ là một lỗi đơn giản thậm chí có thể biến thành yêu cầu thay đổi thiết kế lớn.

Các kích thước của vấn đề giao cắt tính năng này là một sự phức tạp đáng kinh ngạc. Giả sử phiên bản phần mềm hiện tại có Ncác tính năng và bạn thêm một tính năng mới. Chúng ta cũng hãy đơn giản hóa mọi thứ bằng cách nói rằng mỗi tính năng chỉ có thể bật hoặc tắt, sau đó bạn đã có 2^(N+1)các kết hợp tính năng có thể xem xét. Do thiếu từ ngữ / cụm từ tìm kiếm tốt hơn, tôi đề cập đến sự tồn tại của các kết hợp này là vấn đề giao cắt tính năng . (Điểm thưởng cho một câu trả lời bao gồm (các) tham chiếu cho một thuật ngữ được thiết lập nhiều hơn.)

Bây giờ câu hỏi tôi đấu tranh là làm thế nào để đối phó với vấn đề phức tạp này trên từng cấp độ của quá trình phát triển. Vì lý do chi phí rõ ràng, không thực tế đến mức không tưởng, muốn giải quyết từng kết hợp riêng lẻ. Rốt cuộc, chúng tôi cố gắng tránh xa các thuật toán phức tạp theo cấp số nhân vì một lý do chính đáng, nhưng để biến chính quá trình phát triển thành một con quái vật có kích thước theo cấp số nhân chắc chắn sẽ dẫn đến thất bại hoàn toàn.

Vì vậy, làm thế nào để bạn có được kết quả tốt nhất theo cách có hệ thống, không làm bùng nổ bất kỳ ngân sách nào và được hoàn thành một cách tử tế, hữu ích và được chấp nhận một cách chuyên nghiệp.

  • Đặc điểm kỹ thuật: Khi bạn chỉ định một tính năng mới - làm thế nào để bạn đảm bảo rằng nó chơi tốt với tất cả những đứa trẻ khác?

    Tôi có thể thấy rằng người ta có thể kiểm tra một cách có hệ thống từng tính năng hiện có kết hợp với tính năng mới - nhưng điều đó sẽ tách biệt với các tính năng khác. Do tính chất phức tạp của một số tính năng, quan điểm biệt lập này thường liên quan đến mức nó cần một cách tiếp cận có cấu trúc, chứ đừng nói đến 2^(N-1)yếu tố gây ra bởi các tính năng khác mà người ta sẵn sàng bỏ qua.

  • Triển khai: Khi bạn triển khai một tính năng - làm thế nào để bạn đảm bảo mã của mình tương tác / giao nhau đúng cách trong mọi trường hợp.

    Một lần nữa, tôi tự hỏi về sự phức tạp tuyệt đối. Tôi biết các kỹ thuật khác nhau để giảm khả năng lỗi của hai tính năng giao nhau, nhưng không có kỹ thuật nào có thể mở rộng theo bất kỳ cách hợp lý nào. Mặc dù vậy, tôi cho rằng một chiến lược tốt trong đặc tả sẽ giúp giải quyết vấn đề trong quá trình thực hiện.

  • Xác minh: Khi bạn kiểm tra một tính năng - làm thế nào để bạn đối phó với thực tế, rằng bạn chỉ có thể kiểm tra một phần của không gian giao nhau của tính năng này?

    Thật khó để biết rằng việc kiểm tra một tính năng duy nhất trong sự cô lập không đảm bảo bất cứ nơi nào gần mã không có lỗi, nhưng khi bạn giảm nó xuống một phần của 2^-Nnó thì có vẻ như hàng trăm thử nghiệm thậm chí không bao gồm một giọt nước trong tất cả các đại dương kết hợp . Thậm chí tệ hơn, các lỗi có vấn đề nhất là những lỗi xuất phát từ giao điểm của các tính năng, mà người ta có thể không mong đợi dẫn đến bất kỳ vấn đề nào - nhưng làm thế nào để bạn kiểm tra những lỗi này nếu bạn không mong đợi một giao lộ mạnh như vậy?

Mặc dù tôi muốn nghe cách người khác giải quyết vấn đề này, tôi chủ yếu quan tâm đến văn học hoặc các bài viết phân tích chủ đề sâu hơn. Vì vậy, nếu cá nhân bạn theo một chiến lược nhất định, sẽ rất tốt nếu bao gồm các nguồn tương ứng trong câu trả lời của bạn.


6
Một kiến ​​trúc ứng dụng được thiết kế hợp lý có thể chứa các tính năng mới mà không làm đảo lộn thế giới; kinh nghiệm là cấp độ tuyệt vời ở đây. Điều đó nói rằng, một kiến ​​trúc như vậy không phải lúc nào cũng dễ dàng để có được ngay lần thử đầu tiên, và đôi khi bạn phải thực hiện các điều chỉnh khó khăn. Vấn đề kiểm tra không nhất thiết là vấn đề mà bạn đưa ra, nếu bạn biết cách đóng gói đúng các tính năng và chức năng và bao quát chúng bằng các bài kiểm tra đơn vị đầy đủ.
Robert Harvey

Câu trả lời:


5

Chúng tôi đã biết về mặt toán học rằng việc xác minh chương trình là không thể trong thời gian hữu hạn trong trường hợp chung nhất, do vấn đề tạm dừng. Vì vậy, loại vấn đề này không phải là mới.

Trong thực tế, thiết kế tốt có thể cung cấp sự tách rời sao cho số lượng các tính năng giao nhau ít hơn 2 ^ N, mặc dù nó chắc chắn có vẻ cao hơn N ngay cả trong các hệ thống được thiết kế tốt.

Theo như các nguồn tin, đối với tôi, hầu như mọi cuốn sách hay blog về thiết kế phần mềm đều cố gắng giảm 2 ^ N đó một cách hiệu quả nhất có thể, mặc dù tôi không biết bất kỳ vấn đề nào gây ra vấn đề tương tự như bạn làm

Để biết ví dụ về cách thiết kế có thể giúp với điều này, trong bài viết đã đề cập đến một số giao điểm tính năng đã xảy ra vì sao chép và lập chỉ mục đều được kích hoạt của eTag. Nếu họ đã có sẵn một kênh liên lạc khác để báo hiệu sự cần thiết của từng kênh đó thì có thể họ đã kiểm soát thứ tự các sự kiện dễ dàng hơn và có ít vấn đề hơn.

Hoặc, có thể không. Tôi không biết gì về RavenDB. Kiến trúc không thể ngăn chặn các vấn đề giao cắt tính năng nếu các tính năng thực sự đan xen không thể giải thích được và chúng tôi không bao giờ có thể biết trước chúng tôi sẽ không muốn một tính năng thực sự có trường hợp xấu nhất là giao lộ 2 ^ N. Nhưng kiến ​​trúc ít nhất có thể hạn chế các giao lộ do vấn đề thực hiện.

Ngay cả khi tôi sai về RavenDB và eTags (và tôi chỉ sử dụng nó để tranh luận - họ là những người thông minh và có lẽ đã hiểu đúng), thì rõ ràng kiến ​​trúc có thể giúp ích như thế nào . Hầu hết các mẫu mà mọi người nói đến đều được thiết kế rõ ràng với mục tiêu giảm số lượng thay đổi mã theo yêu cầu của các tính năng mới hoặc thay đổi. Điều này quay trở lại - ví dụ: "Các mẫu thiết kế, các yếu tố của phần mềm hướng đối tượng có thể tái sử dụng", phần giới thiệu "Mỗi mẫu thiết kế cho phép một số khía cạnh của kiến ​​trúc thay đổi độc lập với các khía cạnh khác, từ đó làm cho hệ thống trở nên mạnh mẽ hơn đối với một loại cụ thể thay đổi".

Quan điểm của tôi là, người ta có thể hiểu một chút về Big O của các giao điểm tính năng trong thực tế bằng cách, nhìn vào những gì xảy ra trong thực tế. Khi nghiên cứu câu trả lời này, tôi thấy rằng hầu hết các phân tích về các điểm chức năng / nỗ lực phát triển (nghĩa là năng suất) tìm thấy ít hơn mức tăng trưởng tuyến tính của nỗ lực dự án trên mỗi điểm chức năng, hoặc rất cao so với tăng trưởng tuyến tính. Mà tôi thấy hơi ngạc nhiên. Điều này đã có một ví dụ khá dễ đọc.

Điều này (và các nghiên cứu tương tự, một số trong đó sử dụng các điểm chức năng thay vì các dòng mã) không chứng minh giao điểm tính năng không xảy ra và gây ra vấn đề, nhưng có vẻ như bằng chứng hợp lý rằng nó không tàn phá trong thực tế.


0

Đây sẽ không phải là câu trả lời tốt nhất bằng mọi cách, nhưng tôi đã suy nghĩ về một số điều giao nhau với các điểm trong câu hỏi của bạn vì vậy tôi nghĩ rằng tôi đã đề cập đến chúng:

Hỗ trợ về cấu trúc

Từ nhỏ tôi đã thấy, khi các tính năng bị lỗi và / hoặc không kết nối tốt với các tính năng khác, phần lớn là do sự hỗ trợ kém được cung cấp bởi cấu trúc / khung cốt lõi của chương trình để quản lý / điều phối chúng. Dành nhiều thời gian hơn để làm sáng tỏ và làm tròn cốt lõi, tôi nghĩ, nên giảm bớt việc bổ sung các tính năng mới.

Một điều tôi thấy phổ biến trong các ứng dụng nơi tôi làm việc là cấu trúc của một chương trình được thiết lập để xử lý một trong các loại đối tượng hoặc quy trình nhưng rất nhiều phần mở rộng chúng tôi đã thực hiện hoặc muốn thực hiện để làm với việc xử lý nhiều loại. Nếu điều này được tính đến nhiều hơn khi bắt đầu thiết kế của ứng dụng, thì nó sẽ giúp thêm các tính năng này sau.

Điều này trở nên khá quan trọng khi thêm hỗ trợ cho nhiều X liên quan đến mã theo luồng / không đồng bộ / mã theo sự kiện vì công cụ đó có thể bị hỏng khá nhanh - tôi đã rất vui khi gỡ lỗi một số vấn đề liên quan đến vấn đề này.

Có lẽ rất khó để chứng minh loại nỗ lực này ở phía trước, đặc biệt là đối với các nguyên mẫu hoặc dự án một lần - mặc dù một số nguyên mẫu hoặc một lần tiếp tục được sử dụng lại hoặc là (cơ sở) của hệ thống cuối cùng, có nghĩa là chi tiêu sẽ có giá trị trong thời gian dài.

Thiết kế

Khi thiết kế cốt lõi của chương trình, bắt đầu với cách tiếp cận từ trên xuống có thể giúp biến mọi thứ thành các phần có thể quản lý và cho phép bạn quấn đầu xung quanh miền vấn đề; sau đó tôi nghĩ nên sử dụng cách tiếp cận từ dưới lên - điều này sẽ giúp làm cho mọi thứ nhỏ hơn, linh hoạt hơn và tốt hơn để thêm vào sau này. (Như đã đề cập trong liên kết, thực hiện mọi thứ theo cách này giúp triển khai các tính năng nhỏ hơn, có nghĩa là ít xung đột / lỗi hơn.)

Nếu bạn tập trung vào các khối xây dựng cốt lõi của hệ thống và đảm bảo tất cả chúng tương tác tốt, thì mọi thứ được xây dựng bằng chúng cũng có thể sẽ hoạt động tốt và sẽ tích hợp tốt hơn với phần còn lại của hệ thống.

Khi một tính năng mới được thêm vào, tôi nghĩ rằng một lộ trình tương tự có thể được thực hiện khi thiết kế nó như đã được thiết kế phần còn lại của khung: phân tách nó sau đó đi từ dưới lên. Nếu bạn có thể sử dụng lại bất kỳ khối gốc nào từ khung trong việc triển khai tính năng thì điều đó chắc chắn sẽ hữu ích; Khi bạn đã hoàn tất, bạn có thể thêm bất kỳ khối mới nào bạn nhận được từ tính năng này vào các khối đã có trong khung lõi, kiểm tra chúng với bộ khối ban đầu - theo cách đó chúng sẽ tương thích với phần còn lại của hệ thống và có thể sử dụng trong tương lai tính năng là tốt.

Đơn giản hóa!

Tôi đã có lập trường tối giản về thiết kế muộn, bắt đầu bằng việc đơn giản hóa vấn đề, sau đó đơn giản hóa giải pháp. Nếu thời gian có thể được thực hiện trong một giây, đơn giản hóa việc lặp lại thiết kế trên một dự án thì tôi có thể thấy rằng nó rất hữu ích khi thêm những thứ sau này.

Dù sao, đó là 2c của tôi.

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.