Có ai có một ví dụ cụ thể về việc sử dụng Mô hình Flykg không? [đóng cửa]


21

Tôi đã nghiên cứu các mẫu thiết kế và đi qua mô hình trọng lượng bay. Tôi đã cố gắng nhìn thấy các cơ hội để sử dụng mẫu trong các ứng dụng của mình nhưng tôi gặp khó khăn khi xem cách sử dụng nó. Ngoài ra, một số dấu hiệu cho thấy mô hình trọng lượng ruồi đang được sử dụng khi tôi đọc mã người khác là gì?

Theo định nghĩa nó nói:

Sử dụng chia sẻ để hỗ trợ số lượng lớn các đối tượng hạt mịn một cách hiệu quả.

Nếu tôi đọc đúng Từ điển và Hashtables có thể là trường hợp của trọng lượng bay thì điều này có đúng không?

Cảm ơn trước.


7
Chỉ là một giai thoại nhỏ về flyweights: Tôi đã từng phải tạo các tệp excel lớn (tối đa 500 nghìn bản ghi, hơn 100 cột) với API của bên thứ 3. Các phong cách cho các tế bào trở nên cực kỳ bộ nhớ. Vì vậy, bất cứ khi nào cần một kiểu, một hashtable đã được kiểm tra nếu một kiểu bằng nhau đã tồn tại và sau đó chỉ cung cấp một tham chiếu cho kiểu này. Sửa đổi này làm cho xuất khẩu này có thể. Bây giờ có nhiều dữ liệu trong excel là điên rồ theo ý kiến ​​của tôi. Nhưng các bộ điều khiển có các macro phân tích mà họ muốn giữ.
Falcon

9
Nhận xét: Tôi hy vọng rằng những người viết mẫu và sách và bài viết OO sẽ đến với thế giới thực của lập trình viên trung bình và ngừng sử dụng luật sư theo phong cách tiếng Anh!
NoChance

1
"Tôi đã từng phải tạo các tệp excel lớn (lên tới 500 nghìn bản ghi, hơn 100 cột)" - không nhiều so với những gì một số nhà giao dịch có khả năng tạo ;-)
quant_dev

Sau khi đọc một vài ví dụ trong số này, tôi nghĩ rằng việc nén dữ liệu bộ nhớ sẽ là nơi thực thi để thực hiện kỹ thuật này. Cảm ơn đã giúp đỡ!
Jeremy E

Các tế bào bảng trong GWT là flyweights.
dùng16764

Câu trả lời:


19

Một ví dụ là trong các thư viện Java. Java có các kiểu nguyên thủy (ví dụ: intlà số nguyên 32 bit) và các hàm bao cho chúng (ví dụ: Integerbao bọc int). Có các phương pháp để "đóng hộp" một intvào Integervà bỏ hộp Integervào một int. Các hàm bao là cần thiết bởi vì các kiểu nguyên thủy không phải là đối tượng và do đó không thể được sử dụng làm khóa trong Maps hoặc được đặt trong Collections.

Phương thức đấm bốc sử dụng một loạt các vật thể bay như một loại bộ đệm cho Integers tương ứng với intcác giá trị trong khoảng từ -128 đến 127. Vì đó là những giá trị được sử dụng nhiều nhất làm khóa hoặc được đặt trong các bộ sưu tập, nó làm giảm việc sử dụng bộ nhớ và cấp phát. (Nếu có 5000000 Integers đại diện cho giá trị 0 trôi nổi xung quanh, sử dụng bộ nhớ gấp 5000000 lần so với sử dụng lại thể hiện của fly weight).



1
Vì vậy, nhóm thực tập cho các chuỗi trong C # là một ví dụ khác về mô hình cân nặng có đúng không?
Jeremy E

1
@Jeremy E: Vâng, theo ý kiến ​​của tôi, bạn có thể gọi chuỗi thực hiện một ứng dụng của mẫu fly fly, cho các chuỗi, không chỉ về mức tiêu thụ bộ nhớ, mà còn về hiệu quả thời gian chạy.
Falcon

Con trỏ được gắn thẻ Objective-C đưa điều này đến mức cực đoan. Các số nguyên đóng hộp lên tới 56 bit và nhiều chuỗi tối đa sáu ký tự, thậm chí không được phân bổ dưới dạng đối tượng, nhưng tất cả thông tin được đóng gói vào chính con trỏ đối tượng.
gnasher729

9

Đồ họa. Thông thường, một hình ảnh raster (vốn là xương sống của hầu hết đồ họa máy tính ở mức tiêu dùng) là rẻ CPU, nhưng tốn bộ nhớ để hoạt động (điều này tốt vì bộ nhớ rẻ nhưng CPU đắt tiền). Nếu hình ảnh raster đó được lặp đi lặp lại nhiều lần trong việc hiển thị UI lớn hơn (từ các biểu tượng trong ứng dụng GUI của Windows đến các ký tự của phông chữ trong trình xử lý văn bản, đến kết cấu trên các bề mặt trong trò chơi 3D), thì rất có ý nghĩa tải hình ảnh vào bộ nhớ một lần và chỉ cần trỏ nó bằng cách sử dụng các đối tượng rất đơn giản, rẻ tiền để tự tạo và không chiếm nhiều bộ nhớ. Một sprite, chỉ đơn giản là một điểm trong không gian đồ họa mà tại đó hình ảnh sẽ được hiển thị, chỉ là một điểm 3D và một con trỏ bộ nhớ đến pixel đầu tiên của hình ảnh để sử dụng. CÓ THỂ nó cũng bao gồm kích thước của phần tệp hình ảnh được sử dụng, hoặc trong điều khoản đồ họa hoặc bộ nhớ. Thông tin này rất rẻ để thay đổi, giả sử thay đổi hình ảnh hoặc vị trí của sprite, và nó có thể được thực hiện mà không cần tải hình ảnh mới mỗi lần, do đó tăng đáng kể hiệu suất của chương trình bên dưới để thao tác và hiển thị các phần thích hợp của hình ảnh phù hợp để hiển thị một "cảnh" UI hoàn chỉnh.


3

Các Charactertrường hợp phạm vi ASCII trong Smalltalk là flyweights.

Khi bạn đánh giá một cái gì đó như Character space, Character class >> #value:thực thi:

value: anInteger 
    "Answer the Character whose value is anInteger."

    anInteger > 255 ifTrue: [^self basicNew setValue: anInteger].
    ^ CharacterTable at: anInteger + 1.

Biến lớp CharacterTableđược khởi tạo như thế này:

initialize
    "Create the table of unique Characters, and DigitsValues."
    "Character initializeClassificationTable"

    CharacterTable ifNil: [
        "Initialize only once to ensure that byte characters are unique"
        CharacterTable := Array new: 256.
        1 to: 256 do: [:i | CharacterTable
            at: i
            put: (self basicNew setValue: i - 1)]].
    self initializeDigitValues

Vì vậy, khi bạn tạo Chuỗi, các phạm vi ASCII Charactersẽ xuất phát CharacterTablethay vì được tạo mới mỗi lần.


3

Mục đích của việc sử dụng mô hình cân nặng là để tránh khởi tạo đối tượng không cần thiết và do đó tiết kiệm không gian. Theo định nghĩa của GOF , một đối tượng có thể có hai trạng thái, trạng thái bên trong và trạng thái bên ngoài:

  • Trạng thái nội tại: Được lưu trữ trong fly trọng; nó bao gồm các thông tin độc lập trên bối cảnh flyweights, do đó làm cho nó có thể chia sẻ được.
  • Trạng thái bên ngoài: phụ thuộc và thay đổi theo bối cảnh của ruồi và do đó không thể chia sẻ. Các đối tượng khách hàng chịu trách nhiệm chuyển trạng thái bên ngoài đến trọng lượng khi cần.

Giả sử rằng chúng tôi muốn phát triển một ứng dụng soạn thảo văn bản đơn giản trong đó mỗi cột chứa tất cả các hàng của văn bản và hàng có thể chứa các ký tự.

Vấn đề nan giải ở đây là làm thế nào để thiết kế lớp Nhân vật. Lớp char cnhân vật bên trong phải là đối tượng chính (trạng thái nội tại). Tuy nhiên, một char có thể có Phông chữ và Kích thước (trạng thái bên ngoài); do đó chúng ta cần lưu trữ trạng thái bên ngoài của nó trên Hàng (máy khách) và truy cập nó khi cần. Với mục đích này, hai danh sách lưu trữ Phông chữ và Kích cỡ được tạo.

Bằng cách làm theo mẫu Flykg, Nhân vật hiện có thể tái sử dụng và các đối tượng đang được tham chiếu từ một danh sách cụ thể của đối tượng (nhóm cân nặng) có chứa tất cả các ký hiệu ( Characterđối tượng) ASCII .

Đây là những gì tôi mô tả trực quan:

nhập mô tả hình ảnh ở đây

Để in 'xin chào', chỉ cần 4 Characterđối tượng, thay vì 5. Một khi phông chữ được thay đổi, không yêu cầu đối tượng mới; lưu ý rằng điều này sẽ không thể xảy ra nếu chúng ta lưu trữ trạng thái bên ngoài trên lớp Nhân vật, ví dụ:

class Character
{
    char c;
    int Size;
    Font font;

    ....
}

Áp dụng mẫu này trên các bộ dữ liệu lớn sẽ dẫn đến tối ưu hóa đáng kể về độ phức tạp bộ nhớ của ứng dụng và khả năng sử dụng lại đối tượng.

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.