7

Tôi có một ứng dụng rất tập trung vào dữ liệu, được viết bằng Python/PyQt. Tôi đang lập kế hoạch để thực hiện một số phép tái cấu trúc để thực sự tách giao diện người dùng khỏi lõi, chủ yếu là vì chưa có bất kỳ thử nghiệm thực nào tại chỗ và rõ ràng là phải thay đổi.Tiếp cận cấu trúc lại

Đã có một số sự tách biệt rồi, và tôi nghĩ tôi đã làm được một vài điều đúng đắn, nhưng nó hoàn hảo. Hai ví dụ, để hiển thị cho bạn những gì loại điều đang làm phiền tôi:

  • Khi người dùng phải nhấp chuột vào các đại diện của một đối tượng dữ liệu, menu ngữ cảnh bật lên được tạo ra bởi các đối tượng dữ liệu, mặc dù đối tượng dữ liệu này (về bản chất là biểu diễn ORM của một hàng cơ sở dữ liệu) rõ ràng không có gì để làm với giao diện người dùng.

  • Khi nội dung nào đó được ghi vào cơ sở dữ liệu, nhưng ghi không thành công (ví dụ: vì bản ghi cơ sở dữ liệu là bị khóa bởi người dùng khác), hộp thư cổ điển "thử lại/hủy bỏ" được hiển thị cho người dùng. Hộp thoại này được tạo bởi nhà cung cấp dữ liệu *, mặc dù nhà cung cấp rõ ràng không có bất kỳ chức năng giao diện người dùng nào. Rõ ràng, nhà cung cấp có thể tăng ngoại lệ hoặc nói cách khác là không thành công và giao diện người dùng có thể bắt được và hành động tương ứng.

    * đó là từ tôi sử dụng cho đối tượng cơ bản đại diện cho bảng cơ sở dữ liệu và trung gian giữa các đối tượng dữ liệu và công cụ cơ sở dữ liệu; Tôi không chắc chắn cho dù đó là những gì thường được gọi là một "nhà cung cấp"

Tôi không có kinh nghiệm với thử nghiệm, vì vậy tôi không dễ dàng "cảm thấy" vấn đề testability hoặc tương tự, nhưng trước Tôi nhận được vào đó, một số tổ chức lại phải được thực hiện.

Không có logic nghiệp vụ phức tạp nào (chủ yếu chỉ là CRU D , vâng, ngay cả khi không có D), và điều này sẽ được tổ chức lại nhiều hơn viết lại, vì vậy tôi không thực sự quan tâm đến việc giới thiệu các lỗi hồi quy như đã thảo luận trong this question.

Kế hoạch của tôi là bắt đầu tái cấu trúc với ý tưởng rằng phần giao diện người dùng có thể dễ dàng bị tách ra là được thay thế bằng giao diện web hoặc giao diện dựa trên văn bản thay vì giao diện Qt. Mặt khác, Bản thân Qt sẽ vẫn được lõi sử dụng, bởi vì cơ chế tín hiệu/khe được sử dụng ở một vài nơi, ví dụ: đối tượng dữ liệu phát ra tín hiệu changed để cho biết, tốt, bạn biết điều gì.

Vì vậy, câu hỏi của tôi: Đó có phải là cách tiếp cận khả thi để tăng khả năng kiểm tra và bảo trì không? Bất kỳ nhận xét khác, đặc biệt là với Python trong tâm trí?

Trả lời

1

Tôi đã thực hiện tái cấu trúc cho mã kế thừa lớn nhằm phân chia giao diện người dùng/phụ trợ trước đó. Đó là niềm vui và bổ ích.

/khen ngợi;)

Dù mô hình một gọi nó hoặc có thể là một phần của MVC đó là vô giá để có một lớp rất rõ ràng API. Nếu có thể, bạn có thể định tuyến tất cả các yêu cầu giao diện người dùng thông qua một điều phối viên sẽ cung cấp cho bạn quyền kiểm soát tốt hơn đối với giao diện người dùng < -> Giao tiếp logic ví dụ: thực hiện bộ nhớ đệm, auth, vv

Để hình dung:

[QT Frontend] 
[CLIs]    <=======> [Dispatcher] <=> [API] <==> [Core/Model] 
[SOAP/XMPRPC/Json] 
[API Test Suite] 

Bằng cách này

  • nó dễ dàng hơn để thêm bộ kiểm tra để kiểm tra các API của bạn.
  • Ngoài ra, nó còn giúp thêm nhiều giao diện người dùng đồng bộ hơn và dễ dàng hơn.
  • Tài liệu API: Giả sử bạn muốn tài liệu và hiển thị API mặc dù một số giao diện RPC, việc tạo tài liệu API dễ dàng hơn. Nếu ai đó không đồng ý với tầm quan trọng của tài liệu API luôn có thể xem xét API Twitter và thành công của nó.
  • Bạn có thể nhanh chóng nhập lớp API để vỏ python và chơi với nó

API thiết kế có thể xảy ra trước khi bạn bắt đầu mã hóa cho lớp API. Tùy thuộc vào ứng dụng bạn có thể muốn trợ giúp các gói như zinterfaces. Đây là cách tiếp cận chung tôi thực hiện ngay cả khi viết các ứng dụng rất nhỏ và nó chưa bao giờ thất bại đối với tôi.

Đừng nhìn vào

Một lợi thế khác biệt của phương pháp này là sau khi bạn có lớp API và giao diện người dùng mới, bây giờ bạn có thể quay về mã di sản và sửa chữa/cấu trúc lại nó trong có lẽ các bước nhỏ hơn.

Các đề xuất khác là chuẩn bị sẵn bộ thử nghiệm của bạn. Xem lời khuyên của interstar tại What are the first tasks for implementing Unit Testing in Brownfield Applications?.

+0

Bây giờ đó là một ý tưởng thú vị, thích nó! Bạn không xảy ra để có bất kỳ nguồn hoặc tipps liên quan đến điều phối viên? I E. khả năng triển khai khác nhau, có thể cảnh báo, trải nghiệm, v.v.? – balpha

+0

Dispatcher sẽ chuyển tất cả các cuộc gọi API tới tất cả các hệ thống con như trình quản lý bộ nhớ cache, trình duyệt tính hợp lệ, trình ánh xạ URL ... Vì vậy, người điều phối chuyển cuộc gọi API, ngữ cảnh, đối số cho từng hệ thống phụ (tùy thuộc vào các quy tắc nhất định) và cuối cùng gọi API cần thiết. Ban đầu chúng tôi đã cố gắng để có chung thiết kế điều phối để cho phép đăng ký các hệ thống con nhưng sau đó được giải quyết cho người điều phối có kiến ​​thức về cách xử lý các hệ thống con. Thật không may, khung công tác cho các ứng dụng trung tâm API là một nguồn đóng nhưng hiệu ứng lại giống như một chồng trang trí cho mọi API nhưng theo một cách ngầm định. – Shekhar

+0

Ngoài ra xác định và đi qua bối cảnh đã được đóng vai trò rất quan trọng. – Shekhar

7

Nếu bạn chưa làm như vậy, hãy đọc "Làm việc hiệu quả với mã cũ" bởi Michael Feathers - nó đề cập chính xác loại tình huống này và cung cấp nhiều kỹ thuật để xử lý nó.

Một điểm then chốt mà anh ấy thực hiện là thử và thực hiện một số thử nghiệm trước khi tái cấu trúc. Vì nó không thích hợp cho các bài kiểm tra đơn vị, hãy thử để có được một số bài kiểm tra đầu cuối tại chỗ. Tôi tin rằng Qt có khung kiểm thử riêng cho việc điều khiển GUI, vì vậy hãy thêm các kiểm thử để thao tác GUI với một cơ sở dữ liệu đã biết và xác minh kết quả. Khi bạn dọn sạch mã, bạn có thể thay thế hoặc tăng thêm các bài kiểm tra đầu cuối với các bài kiểm tra đơn vị.

+1

Tôi chưa đọc, nhưng tôi đã nhìn thấy nó được đề cập ở một vài nơi, vì vậy tôi chắc chắn sẽ xem xét nó. Cảm ơn. – balpha

2

Nếu bạn muốn trích xuất tất cả các phần GUI của ứng dụng từ tất cả các phần khác để kiểm tra tất cả ứng dụng, bạn nên sử dụng Model-View-Presenter: Bạn có thể tìm thấy một số giải thích herehere.

Với mô hình này, tất cả các dịch vụ của ứng dụng của bạn sử dụng trình diễn trong khi chỉ người dùng mới có thể tương tác trực tiếp với các khung nhìn (phần GUI). Các diễn giả đang quản lý các khung nhìn từ ứng dụng. Bạn sẽ có một phần GUI độc lập với ứng dụng của mình trong trường hợp bạn muốn sửa đổi khung công tác GUI. Điều duy nhất bạn sẽ phải sửa đổi là các diễn giả và chính các quan điểm đó.

Đối với các bài kiểm tra GUI bạn muốn, bạn chỉ cần viết unit tests cho diễn giả. Nếu bạn muốn kiểm tra việc sử dụng GUI, bạn cần phải tạo integration tests.

Hy vọng điều đó sẽ hữu ích!

+0

Vâng, tôi biết về hình mẫu đó và đó là nhiều hơn hoặc ít hơn là tôi đang hướng tới. Trên thực tế, với một số mở rộng đó là những gì tôi đã làm rồi. Vì vậy, tôi lấy câu trả lời của bạn như một gợi ý rằng tôi đang đi đúng hướng :-) Cảm ơn – balpha

+0

Bạn đang chào đón balpha. Tôi nghĩ đây là cách tốt nhất để ứng dụng của bạn dễ kiểm tra hơn. –

1

Một điểm, chưa được đề cập đến và không thực sự trả lời câu hỏi, nhưng rất quan trọng: Bất cứ nơi nào bạn có thể đặt trong thử nghiệm ngay bây giờ, trước khi bạn bắt đầu tái cấu trúc. Điểm chính của thử nghiệm là để phát hiện nếu bạn phá vỡ một cái gì đó.

Tái cấu trúc là thứ mà nó thực sự có giá trị để xem chính xác vị trí tác động của một số thao tác đã thay đổi và trong cùng một cuộc gọi tạo ra một kết quả khác. Đó là những gì tất cả các thử nghiệm này là về: Bạn muốn xem nếu bạn phá vỡ một cái gì đó, bạn muốn xem tất cả những thay đổi không chủ ý.

Vì vậy, hãy kiểm tra ngay bây giờ cho tất cả các phần vẫn sẽ tạo ra kết quả tương tự sau khi tái cấu trúc. Các thử nghiệm không phải là mã hoàn hảo sẽ tồn tại mãi mãi, các thử nghiệm là cho mã cần phải thay đổi, mã cần được sửa đổi, mã sẽ được cấu trúc lại. Các thử nghiệm đang có để đảm bảo việc tái cấu trúc của bạn thực sự làm những gì bạn định làm.

+0

Bạn nói đúng, nó chưa được đề cập rõ ràng, cảm ơn. Đó là một trong những điểm mấu chốt của "Làm việc hiệu quả với Bộ luật cũ" (mà tôi đã đọc trong thời gian chờ đợi), và một cách tiếp cận thú vị cho điều này là trong câu trả lời Stack Overflow mà Shekhar liên kết đến trong câu trả lời của mình. – balpha