Tại sao các phương pháp được bảo vệ không thể bị chặn?


14

Tôi đã tự hỏi tại sao không thể tạo plugin cho protectedcác phương thức. Có đoạn mã này trong Magento\Framework\Interception\Code\Generator\Interceptor:

protected function _getClassMethods()
{
    $methods = [$this->_getDefaultConstructorDefinition()];

    $reflectionClass = new \ReflectionClass($this->getSourceClassName());
    $publicMethods = $reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC);
    foreach ($publicMethods as $method) {
        if ($this->isInterceptedMethod($method)) {
            $methods[] = $this->_getMethodInfo($method);
        }
    }
    return $methods;
}

Nó kiểm tra nếu phương thức là publictrước khi cho phép nó bị chặn. Nó có thể dễ dàng thay đổi bằng cách tạo ra một preferencetrong di.xmlcác mô-đun riêng, tất nhiên, như thế này:

<?xml version="1.0"?>
<config>
    <preference for="Magento\Framework\Interception\Code\Generator\Interceptor" type="MyVendor\MyModule\Model\MyInterceptorModel" />
</config>

và viết lại _getClassMethodsvới sự \ReflectionMethod::IS_PUBLICthay đổi \ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTEDbên trong của phương thức.

Nhưng tôi tự hỏi tại sao không thể chặn các phương thức được bảo vệ trong định nghĩa phương thức ban đầu? Liệu nó có ảnh hưởng lớn đến hiệu suất, hoặc có một số lý do khác cho điều đó, như cho phép các mô-đun của bên thứ 3 làm cho logic Magento quá "lộn xộn"?

Câu trả lời:


24

Theo tài liệu của Magento, việc sử dụng một plugin trên một phương thức được bảo vệ là không thể.

( http://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html )

Bạn không thể áp dụng bổ trợ cho:

  • Phương pháp cuối cùng
  • Lớp cuối cùng
  • Bất kỳ lớp nào chứa ít nhất một phương thức công khai cuối cùng
  • Phương pháp không công khai
  • Các phương thức lớp (như phương thức tĩnh)
  • __construct Các loại ảo

Nhưng quan điểm của bạn là chính xác, theo ___callPluginsđịnh nghĩa trong Magento\Framework\Interception\Interceptor, tôi không thấy bất kỳ vấn đề nào khi sử dụng các phương pháp được bảo vệ.

Tôi đoán đầu tiên là họ đã hạn chế nó để tránh sự phức tạp mã cao vì Magento nên viết lại bất kỳ phương thức được bảo vệ nào và gọi ___callPluginscho từng phương thức đó ... nó sẽ làm chậm IMHO một cách khủng khiếp.

Nhưng tôi nghĩ lý do thực sự là vì sự đồng thuận logic: các plugin nên được sử dụng để thay đổi đầu ra / đầu vào của phương thức lớp , không phải viết lại hành vi nội bộ, vì vậy chúng chỉ nên truy cập các phương thức công khai.

Để viết lại một hành vi nội bộ, bạn phải sử dụng một ưu tiên. Nó có ý nghĩa.


1
Câu trả lời tốt. Bản thân tôi cũng đã tự hỏi điều này nhưng theo quan điểm OOP / RẮN thì chỉ nên cho phép các phương thức công khai bị chặn.
Giel Berkers

13

Nếu tôi nhớ chính xác từ một bài thuyết trình của Anton Krill, anh ta nói rằng các phương pháp được bảo vệ về mặt kỹ thuật có thể bị chặn, nhưng nó đánh bại mục đích để chúng được "bảo vệ".
Lớp đánh chặn được tự động mở rộng lớp gốc để nó có quyền truy cập vào các phương thức được bảo vệ.
Nhưng ... Các phương thức được bảo vệ không nên có sẵn bên ngoài lớp học.
Vì vậy, đó là một quyết định nhiều hơn là một giới hạn.


-4

Đây là tính năng bảo mật OOPS không phải là magento cụ thể.

Phương thức công khai, được dán nhãn bởi công chúng có sẵn cho mọi lớp. Các phương thức được bảo vệ, được gắn nhãn bởi được bảo vệ có sẵn cho các lớp con và các lớp thân thiện, là các lớp trong cùng một gói. Các phương thức thân thiện, được gắn nhãn bởi không có gì (tức là mặc định) có sẵn cho các lớp thân thiện. Các phương thức riêng chỉ có sẵn cho chính lớp đó.

Lý do:

1) Phương pháp được bảo vệ không thể truy cập ở cấp độ Kế thừa thứ hai.

ví dụ: Hãy lấy một ví dụ hai lớp Class A & Class B trong cùng một gói.

Lớp B chỉ có thể được bảo vệ kế thừa cũng như các phương thức công khai của lớp A.


4
Protected methods... which are classes in the same package- Đây không phải là sự thật. Các phương thức được bảo vệ chỉ có sẵn cho các lớp có sẵn trong cùng một hệ thống phân cấp thông qua kế thừa - cho dù chúng có trong cùng một gói hay không không có sự khác biệt. Protected Methods can't access in Inheritence second level.- một lần nữa, không đúng - các phương thức được bảo vệ có sẵn ở bất kỳ mức độ kế thừa nào, chỉ không từ bên ngoài phạm vi đối tượng
Robbie Averill
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.