Là một số vấn đề nhất định được giải quyết thanh lịch hơn với AOP?


19

Tôi đã nảy ra ý tưởng về Lập trình hướng theo khía cạnh và tôi có một số lo ngại với nó.

Ý tưởng cơ bản dường như là chúng ta muốn có những mối quan tâm xuyên suốt mà không được mô đun hóa tốt bằng cách sử dụng đối tượng và mô đun hóa chúng. Đó là tất cả rất tốt và tốt.

Nhưng việc triển khai AOP dường như là sửa đổi mã từ bên ngoài mô-đun. Vì vậy, ví dụ, một khía cạnh có thể được viết để thay đổi những gì xảy ra khi một đối tượng cụ thể được truyền dưới dạng tham số trong hàm. Điều này dường như đi ngược lại với ý tưởng của các mô-đun. Tôi không thể sửa đổi hành vi của một mô-đun từ bên ngoài mô-đun đó, nếu không thì toàn bộ điểm của các mô-đun bị đảo ngược. Nhưng các khía cạnh dường như đang làm chính xác điều đó!

Về cơ bản, các khía cạnh dường như là một hình thức vá mã. Nó có thể hữu ích cho một số hack nhanh chóng; nhưng, như một nguyên tắc chung có lẽ nó không phải là điều bạn muốn làm. Lập trình định hướng theo khía cạnh đối với tôi có một thực tiễn tồi và nâng lên một nguyên tắc thiết kế chung.

AOP có phải là một thực hành tốt? Là một số vấn đề lập trình nhất định được giải quyết thanh lịch hơn với AOP?


ahhh, bản vá khỉ nổi tiếng!
Muad'Dib

1
Tôi đã chỉnh sửa câu hỏi để cải thiện giọng điệu và bỏ phiếu để mở lại.
Robert Harvey

Questio cũng đã được hỏi lại dưới một hình thức khác ở đây: lập trình
Peter Boughton

Câu trả lời:


19

Lập trình hướng theo khía cạnh cho phép thực hiện một số loại lập trình khó thực hiện mà không cần mã phân tán không cần thiết trong toàn bộ ứng dụng hoặc thư viện không liên quan đến các chức năng chính của phần mềm của bạn (nghĩa là mối quan tâm xuyên suốt). Những ví dụ bao gồm:

  1. Ghi nhật ký và giám sát
  2. Phân tích hiệu suất
  3. Gỡ lỗi và truy tìm
  4. Hoàn tác chức năng
  5. Xác nhận đầu vào và đầu ra
  6. Biến đổi hành vi của các đối tượng hiện có
  7. Bộ lọc đối tượng
  8. Thực hiện bảo mật
  9. Quản lý giao dịch

Bằng cách giới hạn các mối quan tâm xuyên suốt như vậy cho một phần của ứng dụng và sau đó tham chiếu các tính năng này trong mã thông qua các thuộc tính, chặn cuộc gọi phương thức hoặc proxy động, bạn cho phép đóng gói hành vi cắt chéo; điều này có tất cả các lợi ích (tức là một điểm sửa đổi) đóng gói sẽ cung cấp bất cứ nơi nào khác trong ứng dụng của bạn.

Điểm mấu chốt ở đây là AOP gói gọn hành vi 1) phổ biến trong toàn bộ ứng dụng và 2) ngoại vi đối với chức năng chính của ứng dụng.


7

Đến muộn trong trò chơi, nhưng tôi cung cấp điều này cho các nhà phát triển sau này có thể vấp phải câu hỏi này.

Tôi thực sự khuyên bạn nên chống lại AOP nếu ứng dụng của bạn phụ thuộc vào nó để hoạt động chính xác. Các khía cạnh hoạt động như thế này:

  • Lời khuyên (hành vi bổ sung) được áp dụng cho
  • Tham gia các điểm (những nơi có thể gắn mã bổ sung, như một phương thức bắt đầu hoặc kết thúc hoặc khi một sự kiện đã kích hoạt)
  • ... trong đó điểm cắt (một mẫu phát hiện xem các điểm nối đã cho có khớp hay không)

Đối với bất cứ ai đã làm máy tính trong một thời gian dài, thực tế là các mẫu được sử dụng có thể là một cái gì đó để xem xét kỹ. Vì vậy, đây là một ví dụ về một điểm cắt phù hợp với bất kỳ phương thức nào được đặt tên setbất kể đối số:

call(* set(..))

Vì vậy, đó là một điểm khá sâu rộng và rõ ràng là nên xử lý việc này một cách cẩn thận (không có ý định chơi chữ) vì bạn đang áp dụng lời khuyên cho nhiều việc.

Hoặc chết tiệt, hãy áp dụng lời khuyên cho tất cả mọi thứ , bất kể tên hoặc chữ ký!

execution(* *(..))

Vì vậy, rõ ràng chúng ta nên cẩn thận vì có rất nhiều sức mạnh ở đây, nhưng đây không phải là một cuộc tranh cãi với các khía cạnh - đó là một lập luận cần thận trọng bởi vì có rất nhiều sức mạnh ở đây và việc khớp mẫu có thể dễ dàng bị phá vỡ (chỉ cần nhấn vào công cụ tìm kiếm yêu thích của bạn aop lỗi và vui chơi).

Vì vậy, đây là những gì trông giống như một điểm cắt tương đối an toàn:

pointcut setter(): target(Point) &&
                   ( call(void setX(int)) ||
                     call(void setY(int)) );

Điều đó cung cấp lời khuyên rõ ràng nếu các phương thức được đặt tên setXhoặc setYtrên một Pointđối tượng được tìm thấy. Các phương thức chỉ có thể nhận ints và chúng phải được void. Trông khá an toàn, phải không? Chà, điều đó an toàn nếu những phương pháp đó tồn tại và bạn đã áp dụng lời khuyên chính xác. Nếu không, quá tệ; Nó âm thầm thất bại.

Để đưa ra một ví dụ, một người bạn đã cố gắng gỡ lỗi một ứng dụng Java trong đó mọi người một lần trong một thời gian tuyệt vời, nó sẽ trả về dữ liệu không chính xác. Đó là một thất bại không thường xuyên và dường như không tương quan với bất kỳ sự kiện hoặc dữ liệu cụ thể nào. Đó là một lỗi luồng, một cái gì đó rất khó kiểm tra hoặc phát hiện. Hóa ra, họ đã sử dụng các khía cạnh để khóa các phương thức và làm cho chúng trở thành "luồng an toàn", nhưng một lập trình viên đã đổi tên một phương thức và một điểm cắt không khớp với nó, do đó gây ra sự phá vỡ im lặng của ứng dụng.

Vì vậy, tôi nói với mọi người rằng nếu họ phải sử dụng AOP, để xử lý các khía cạnh như ngoại lệ: trong một hệ thống được thiết kế tốt và nếu không có gì sai, họ có thể gỡ bỏ và phần mềm vẫn hoạt động chính xác. Tuy nhiên, nếu chức năng của chương trình phụ thuộc vào AOP, bạn giới thiệu một sự mong manh cho chương trình của bạn là không chính đáng.

Vì vậy, ghi nhật ký, gỡ lỗi và truy tìm là những ví dụ tuyệt vời về hành vi hoàn hảo cho các khía cạnh, nhưng bảo mật? Không. Chủ đề an toàn? Không.

Để thay thế mạnh mẽ cho AOP, xem các đặc điểm . Thay vì được gắn vào ngôn ngữ, chúng được tích hợp trực tiếp vào ngôn ngữ, không cần IDE "nhận biết đặc điểm" (mặc dù nó có thể giúp đỡ) và có lỗi thời gian biên dịch nếu không có phương pháp bạn yêu cầu. Các đặc điểm thực hiện công việc sạch sẽ hơn nhiều trong việc xử lý tách các mối quan tâm vì vấn đề được xác định rõ hơn ngay từ đầu. Tôi sử dụng chúng rộng rãi và chúng thật tuyệt vời.


Thay vì cho rằng AOP không nên được sử dụng cho chức năng cốt lõi, có thể thích hợp hơn để nói rằng việc cắt điểm dựa vào tên phương thức là một ý tưởng tồi. Có lẽ tôi cũng cho rằng việc khóa và đồng bộ hóa cũng không phải là trường hợp sử dụng tốt cho AOP.
Mã Bling

2

Một tình huống trong đó AOP có thể là giải pháp tốt nhất cũng như thực tế là khi bạn không có quyền truy cập vào mã nguồn . Để sử dụng ví dụ cũ mệt mỏi của mối quan tâm xuyên suốt Logging:

Giả sử bạn muốn ghi lại luồng kiểm soát trong thư viện bên thứ ba mà bạn tiêu thụ. Bạn có mã riêng của mình đầy đủ với các báo cáo đăng nhập. Tuy nhiên, đối với thư viện này, bạn không có nguồn, khiến cho không thể thêm các báo cáo đăng nhập của bạn. Vì bạn làm có bytecode, AOP cho phép bạn cụ mà bên thứ ba thư viện anyway.

Và nếu bạn đang tạo một khía cạnh Ghi nhật ký, bạn cũng có thể xem xét triển khai Ghi nhật ký với AOP theo máng mã của riêng bạn.


Ghi nhật ký là cho những điều "thú vị". Làm thế nào bạn có thể làm những việc khác ngoài "nhập với các tham số này" và "thoát" với ghi nhật ký AOP?

@Thorbjorn: Ghi nhật ký / gỡ lỗi / theo dõi chỉ là một trong nhiều lĩnh vực chức năng mà AOP có thể trợ giúp. Tôi đã sử dụng nó như một ví dụ để minh họa quan điểm của tôi. Điểm tôi đang cố gắng thực hiện là AOP cho phép bạn kiểm soát nhiều hơn mã byte của bên thứ ba.
Joseph Tanenbaum

chắc chắn, nhưng tôi thực sự muốn biết liệu ghi nhật ký AOP có thể làm được nhiều hơn ngoài việc ghi nhật ký nhập không?

Nó phụ thuộc vào công cụ AOP bạn sử dụng, nhưng chắc chắn có giới hạn cho những gì bạn có thể làm. Rất có thể không thể vượt ra ngoài đăng nhập xuất nhập cảnh.
Joseph Tanenbaum
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.