PECS (Producer Extends Consumer Super)
اگر فقط اقلامی را از یک مجموعه عمومی میکشید، این یک تولیدکننده است و باید از extends استفاده کنید. اگر فقط اقلام را داخل آن پر می کنید، مصرف کننده است و باید از super استفاده کنید. اگر هر دو را با یک مجموعه انجام می دهید، نباید از extends یا super استفاده کنید.
فرض کنید متدی دارید که مجموعهای از چیزها را به عنوان پارامتر خود در نظر میگیرد، اما میخواهید انعطافپذیرتر از پذیرش یک Collection<? extends Thing>باشد.
مورد 1: می خواهید مجموعه را مرور کنید و با هر مورد کارهایی انجام دهید.
در این صورت لیست یک تولید کننده است، بنابراین باید از یک Collection<? extends Thing> استفاده کنید.
دلیلش این است که یک مجموعه Collection<? extends Thing> میتواند هر زیرگروهی از Thing را در خود جای دهد، و بنابراین هر عنصر زمانی که عملیات خود را انجام میدهید مانند یک Thing رفتار میکند. (شما در واقع نمی توانید چیزی (به جز null) را به یک مجموعه Collection<? extends Thing> اضافه کنید، زیرا در زمان اجرا نمی توانید بدانید که کدام زیرگروه خاصی از Thing در مجموعه وجود دارد.
مورد 2: می خواهید چیزهایی را به مجموعه اضافه کنید.
در این صورت لیست یک مصرف کننده است، بنابراین باید از یک Collection<? super Thing> استفاده کنید.
دلیلش در اینجا آن است که برخلاف مجموعه Collection<? extends Thing>، مجموعه Collection<? super Thing> همیشه می تواند یک Thing
را بدون توجه به نوع پارامتر واقعی آن نگه دارد. در اینجا برای شما مهم نیست که چه چیزی قبلاً در لیست است تا زمانی که اجازه می دهد یک Thing اضافه شود. این چیزی است که ? super Thing تضمین می کند.
اصول PECS در علوم کامپیوتر
- Covariance:
? extends MyClass
, - Contravariance:
? super MyClass
and - Invariance/non-variance:
MyClass
تصویر زیر این مفهوم را توضیح میدهد:
"PECS" is from the collection's point of view. If you are only pulling items from a generic collection, it is a producer and you should use extends
; if you are only stuffing items in, it is a consumer and you should use super
. If you do both with the same collection, you shouldn't use either extends
or super
.