Sự khác nhau giữa Proxy và Mẫu trang trí


136

Bạn có thể đưa ra bất kỳ lời giải thích tốt nào về sự khác biệt giữa ProxyDecorator không?

Sự khác biệt chính mà tôi thấy là khi chúng ta giả sử rằng Proxy sử dụng bố cục và Trình trang trí sử dụng tổng hợp thì dường như rõ ràng rằng bằng cách sử dụng nhiều (một hoặc nhiều) Trình trang trí, bạn có thể sửa đổi / thêm chức năng cho phiên bản có sẵn (trang trí), trong khi Proxy có phiên bản bên trong của lớp proxy và ủy quyền cho nó thêm một số tính năng bổ sung (hành vi proxy).

Câu hỏi là - Proxy được tạo với tổng hợp vẫn là Proxy hay đúng hơn là Trình trang trí ? Có được phép (theo định nghĩa trong các mẫu GoF) để tạo Proxy với tổng hợp không?


2
Một số liên kết: Proxytrang trí
Sotirios Delimanolis

5
Trường hợp bạn có ý tưởng rằng Proxy sử dụng bố cục và Trình trang trí sử dụng tổng hợp?
CPerkins

1
@CPerkins xem bình luận của tôi cho câu trả lời của Rahul Tripathi.
ukasz Rzeszotarski

1
Và cũng có thể trang trí ( patterns.cs.up.ac.za/examples/ch2/decorator-theory.cs ) - rõ ràng là tập hợp, proxy ( patterns.cs.up.ac.za/examples/ch2/proxy-theory.cs ) - rõ ràng là thành phần.
hyankov 13/03/2016

Câu trả lời:


16

Đây là trích dẫn trực tiếp từ GoF (trang 216).

Mặc dù các nhà trang trí có thể có các triển khai tương tự như các proxy, các nhà trang trí có một mục đích khác. Trình trang trí thêm một hoặc nhiều trách nhiệm cho một đối tượng, trong khi proxy kiểm soát quyền truy cập vào một đối tượng.

Proxy khác nhau ở mức độ mà chúng được thực hiện như một người trang trí. Một proxy bảo vệ có thể được thực hiện chính xác như một người trang trí. Mặt khác, một proxy từ xa sẽ không chứa tham chiếu trực tiếp đến chủ đề thực của nó mà chỉ là một tham chiếu gián tiếp, chẳng hạn như "ID máy chủ và địa chỉ cục bộ trên máy chủ". Một proxy ảo sẽ bắt đầu với một tham chiếu gián tiếp như tên tệp nhưng cuối cùng sẽ có được và sử dụng một tham chiếu trực tiếp.

Các câu trả lời phổ biến chỉ ra rằng Proxy biết loại cụ thể của đại biểu. Từ trích dẫn này, chúng ta có thể thấy điều đó không phải lúc nào cũng đúng.

Sự khác biệt giữa Proxy và Trình trang trí theo GoF là Proxy hạn chế ứng dụng khách. Trang trí không. Proxy có thể hạn chế những gì khách hàng làm bằng cách kiểm soát quyền truy cập vào chức năng; hoặc nó có thể hạn chế những gì khách hàng biết bằng cách thực hiện các hành động vô hình và không xác định đối với khách hàng. Decorator làm ngược lại: nó tăng cường những gì đại biểu của nó làm theo cách hiển thị cho khách hàng.

Chúng tôi có thể nói rằng Proxy là một hộp đen trong khi Decorator là một hộp màu trắng.

Mối quan hệ thành phần giữa trình bao bọc và đại biểu là mối quan hệ sai để tập trung vào khi tương phản Proxy với Trình trang trí, bởi vì bố cục là tính năng mà hai mẫu này có điểm chung. Mối quan hệ giữa trình bao bọc và ứng dụng khách là điểm khác biệt của hai mẫu này.

  • Decorator thông báo và trao quyền cho khách hàng của mình.
  • Proxy hạn chế và không cho phép khách hàng của nó.

113

Sự khác biệt thực sự không phải là quyền sở hữu (thành phần so với tổng hợp), mà là thông tin loại.

Một Decoratorluôn luôn trôi qua được ủy quyền của nó. Một Proxy có thể tự tạo ra nó hoặc anh ta có thể đã tiêm nó.

Nhưng một Proxy luôn biết loại (cụ thể hơn) của đại biểu. Nói cách khác, Proxy và đại biểu của nó sẽ có cùng loại cơ sở, nhưng Proxy trỏ đến một số loại dẫn xuất. Một trang trí chỉ đến loại cơ sở riêng của mình. Do đó, sự khác biệt là trong thông tin thời gian biên dịch về loại đại biểu.

Trong một ngôn ngữ động, nếu đại biểu được tiêm và tình cờ có cùng giao diện, thì không có sự khác biệt.

Câu trả lời cho câu hỏi của bạn là có".


2
"Nhưng một Proxy luôn biết loại (cụ thể hơn) của đại biểu." Tôi không nghĩ đó là sự thật. Hãy tưởng tượng proxy từ xa. Cơ chế ủy quyền không cần biết bất kỳ chi tiết cụ thể nào của đối tượng từ xa. Hệ thống từ xa đăng ký đối tượng với giao diện đã chỉ định. Và proxy cục bộ hiển thị giao diện tương tự.
Alexey

3
Tôi đã tham gia một lớp học về điều này tại Amazon từ một giảng viên thỉnh giảng, người biết công cụ của mình. Có một sự khác biệt giữa việc sử dụng "proxy" thực thi (ví dụ với dịch vụ web) và Mẫu thiết kế proxy. Các UML của mẫu Proxy và của mẫu Trang trí có thể khác nhau. Nhưng không có gì ngăn Proxy có cùng API với người được ủy quyền. Trình trang trí là một tập hợp con nghiêm ngặt của Proxy, nhưng Trình trang trí vẫn có thể được gọi là Proxy tùy thuộc vào việc API cơ bản có được đảm bảo giống nhau hay không.
cdunn2001

85

Mẫu trang trí tập trung vào việc thêm động các chức năng vào một đối tượng, trong khi Mẫu Proxy tập trung vào việc kiểm soát quyền truy cập vào một đối tượng.

BIÊN TẬP:-

Mối quan hệ giữa Proxy và chủ thể thực thường được đặt ở thời gian biên dịch, Proxy khởi tạo nó theo một cách nào đó, trong khi Decorator được gán cho chủ thể khi chạy, chỉ biết giao diện của chủ thể.


5
Một Proxy vẫn có thể được sử dụng để thêm chức năng. Hãy nghĩ về proxy AOP.
Sotirios Delimanolis

5
Hoàn toàn đồng ý thưa ngài. Tôi sẽ chuyển đổi theo cách khác những gì tôi muốn nói với Proxy Proxy, lớp proxy có thể ẩn thông tin chi tiết của một đối tượng khỏi máy khách của nó. Do đó, khi sử dụng Mẫu Proxy, chúng tôi thường tạo một thể hiện loại bỏ bên trong lớp proxy. Và khi sử dụng Mẫu trang trí, chúng ta thường chuyển đối tượng ban đầu làm tham số cho hàm tạo của trình trang trí.
Rahul Tripathi

Trong trường hợp này khi cá thể bị 'ẩn' trong proxy, sự khác biệt là rõ ràng đối với tôi (như tôi đã viết) tuy nhiên tôi nghĩ rằng mọi người thường gọi là các lớp proxy lấy đối tượng proxy được truyền làm tham số của hàm tạo. Trong trường hợp này, sự khác biệt của việc thêm chức năng mới hoặc kiểm soát là (rất) mỏng đối với tôi.
ukasz Rzeszotarski

5
Mối quan hệ giữa Proxy và chủ thể thực thường được đặt ở thời gian biên dịch, Proxy khởi tạo nó theo một cách nào đó, trong khi Trình trang trí hoặc Bộ điều hợp được gán cho chủ thể trong thời gian chạy, chỉ biết giao diện của chủ thể. Hy vọng rằng có ý nghĩa !!! :)
Rahul Tripathi

1
Nó không bạn có thể thêm dòng này vào câu trả lời của bạn.
ukasz Rzeszotarski

49

Trình trang trí lấy tham chiếu cho đối tượng được trang trí (thường thông qua hàm tạo) trong khi Proxy chịu trách nhiệm tự làm điều đó.

Proxy hoàn toàn không thể khởi tạo đối tượng gói (như thế này làm ORM để ngăn truy cập không cần thiết vào DB nếu trường / getters đối tượng không được sử dụng) trong khi Decorator luôn giữ liên kết đến trường hợp được bao bọc thực tế.

Proxy thường được sử dụng bởi các khung để thêm bảo mật hoặc bộ nhớ đệm / laze và được xây dựng theo khung (không phải bởi chính nhà phát triển thông thường).

Trình trang trí thường được sử dụng để thêm hành vi mới vào các lớp cũ hoặc cũ bởi chính nhà phát triển dựa trên giao diện chứ không phải lớp thực tế (vì vậy nó hoạt động trên nhiều trường hợp giao diện, Proxy nằm xung quanh lớp cụ thể).


22

Sự khác biệt chính:

  1. Proxy cung cấp giao diện tương tự. Trang trí cung cấp một giao diện nâng cao.
  2. DecoratorProxy có các mục đích khác nhau nhưng cấu trúc tương tự nhau. Cả hai đều mô tả làm thế nào để cung cấp một mức độ gián tiếp cho một đối tượng khác và việc triển khai giữ một tham chiếu đến đối tượng mà họ chuyển tiếp yêu cầu.
  3. Trang trí có thể được xem như là một hỗn hợp thoái hóa chỉ với một thành phần. Tuy nhiên, Trình trang trí thêm các trách nhiệm bổ sung - nó không dành cho tổng hợp đối tượng.
  4. Trang trí hỗ trợ thành phần đệ quy
  5. Lớp Decorator tuyên bố mối quan hệ thành phần với giao diện LCD (Mẫu số thấp nhất) và thành viên dữ liệu này được khởi tạo trong hàm tạo của nó.
  6. Sử dụng Proxy để khởi tạo lười biếng, cải thiện hiệu suất bằng cách lưu trữ đối tượng và kiểm soát quyền truy cập vào máy khách / người gọi

Bài viết của Sourcemaking trích dẫn những điểm tương đồng và khác biệt một cách xuất sắc.

Các câu hỏi / liên kết SE liên quan:

Khi nào nên sử dụng mẫu trang trí?

Sự khác biệt chính xác giữa các mẫu Adaptor và Proxy là gì?


3

Proxy và Decorator khác nhau về mục đích và nơi họ tập trung vào việc thực hiện nội bộ. Proxy là để sử dụng một đối tượng từ xa, quá trình chéo hoặc mạng chéo như thể nó là một đối tượng cục bộ. Trang trí là để thêm hành vi mới vào giao diện ban đầu.

Mặc dù cả hai mẫu đều có cấu trúc tương tự nhau, phần lớn sự phức tạp của Proxy nằm ở việc đảm bảo liên lạc đúng với đối tượng nguồn. Mặt khác, Decorator tập trung vào việc thực hiện các hành vi được thêm vào.


Bạn đang nói gì khác với 4 câu trả lời khác đã có ở đây?
Stephen Rauch

Tôi không biết nếu nó ở đó. Tôi chỉ cảm thấy thôi thúc sau khi đọc những câu trả lời trước đó.
James Lin

1

Mất một lúc để tìm ra câu trả lời này và ý nghĩa thực sự của nó. Một vài ví dụ sẽ làm cho nó rõ ràng hơn.

Proxy Đầu tiên:

public interface Authorization {
    String getToken();
} 

Và:

// goes to the DB and gets a token for example
public class DBAuthorization implements Authorization {
    @Override
    public String getToken() {
        return "DB-Token";
    }
}

Và có một người gọi điều này Authorization, một người khá ngu ngốc:

class Caller {
    void authenticatedUserAction(Authorization authorization) {
        System.out.println("doing some action with : " + authorization.getToken());
    }
}

Không có gì khác thường cho đến nay, phải không? Nhận mã thông báo từ một dịch vụ nhất định, sử dụng mã thông báo đó. Bây giờ đến một yêu cầu nữa cho hình ảnh, thêm ghi nhật ký: có nghĩa là đăng nhập mã thông báo mỗi lần. Thật đơn giản cho trường hợp này, chỉ cần tạo một Proxy:

public class LoggingDBAuthorization implements Authorization {

    private final DBAuthorization dbAuthorization = new DBAuthorization();

    @Override
    public String getToken() {
        String token = dbAuthorization.getToken();
        System.out.println("Got token : " + token);
        return token;
    }
}

Làm thế nào chúng ta sẽ sử dụng điều đó?

public static void main(String[] args) {
    LoggingDBAuthorization loggingDBAuthorization = new LoggingDBAuthorization();

    Caller caller = new Caller();
    caller.authenticatedUserAction(loggingDBAuthorization);
}

Lưu ý rằng LoggingDBAuthorization giữ một ví dụ của DBAuthorization. Cả hai LoggingDBAuthorizationDBAuthorization thực hiện Authorization .

  • Một proxy sẽ giữ một số triển khai cụ thể ( DBAuthorization) của giao diện cơ sở ( Authorization). Nói cách khác, một Proxy biết chính xác những gì đang được ủy quyền.

Decorator:

Nó bắt đầu khá giống với Proxy, với một giao diện:

public interface JobSeeker {
    int interviewScore();
}

và thực hiện nó:

class Newbie implements JobSeeker  {
    @Override
    public int interviewScore() {
        return 10;
    }
}

Và bây giờ chúng tôi muốn thêm một ứng viên có kinh nghiệm hơn, thêm điểm phỏng vấn cộng với điểm khác JobSeeker:

@RequiredArgsConstructor 
public class TwoYearsInTheIndustry implements JobSeeker {

    private final JobSeeker jobSeeker;

    @Override
    public int interviewScore() {
        return jobSeeker.interviewScore() + 20;
    } 
}

Lưu ý cách tôi nói rằng cộng với một từ một JobSeeker khác , không Newbie . A Decoratorkhông biết chính xác nó đang trang trí gì, nó chỉ biết hợp đồng của trường hợp được trang trí đó (nó biết về nó JobSeeker). Hãy lưu ý ở đây rằng điều này không giống như mộtProxy ; rằng, ngược lại, biết chính xác những gì nó đang trang trí.

Bạn có thể đặt câu hỏi liệu thực sự có sự khác biệt nào giữa hai mẫu thiết kế trong trường hợp này không? Điều gì xảy ra nếu chúng ta cố gắng viết Decoratornhư một Proxy?

public class TwoYearsInTheIndustry implements JobSeeker {

    private final Newbie newbie = new Newbie();

    @Override
    public int interviewScore() {
        return newbie.interviewScore() + 20;
    }
}

Đây chắc chắn là một lựa chọn và làm nổi bật mức độ gần gũi của các mẫu này; chúng vẫn dành cho các kịch bản khác nhau như được giải thích trong các câu trả lời khác.


1

Proxy cung cấp cùng một giao diện cho đối tượng được bao bọc, Decorator cung cấp cho nó một giao diện nâng cao và Proxy thường tự mình quản lý vòng đời của đối tượng dịch vụ, trong khi thành phần của Decorator luôn được điều khiển bởi máy khách.

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.