Lý lịch
Đây là vấn đề thực tế tôi đang giải quyết: Tôi muốn có một cách để thể hiện các lá bài trong trò chơi bài Magic: The Gathering . Hầu hết các thẻ trong trò chơi là các thẻ trông bình thường, nhưng một số thẻ được chia thành hai phần, mỗi phần có tên riêng. Mỗi nửa của hai thẻ này được coi là một thẻ. Vì vậy, để rõ ràng, tôi sẽ Card
chỉ sử dụng để chỉ một cái gì đó là thẻ thông thường hoặc một nửa của thẻ hai phần (nói cách khác, một cái gì đó chỉ có một tên).
Vì vậy, chúng tôi có một loại cơ sở, Thẻ. Mục đích của các đối tượng này thực sự chỉ là để giữ các thuộc tính của thẻ. Họ không thực sự làm bất cứ điều gì một mình.
interface Card {
String name();
String text();
// etc
}
Có hai lớp con Card
mà tôi đang gọi PartialCard
(một nửa thẻ hai phần) và WholeCard
(thẻ thông thường). PartialCard
có hai phương pháp bổ sung: PartialCard otherPart()
và boolean isFirstPart()
.
Đại diện
Nếu tôi có một cỗ bài, nó nên bao gồm WholeCard
s, không phải Card
s, vì nó Card
có thể là một PartialCard
, và điều đó sẽ không có ý nghĩa. Vì vậy, tôi muốn một đối tượng đại diện cho "thẻ vật lý", nghĩa là một thứ có thể đại diện cho một WholeCard
hoặc hai PartialCard
s. Tôi đang tạm gọi loại này Representative
, và Card
sẽ có phương pháp getRepresentative()
. A Representative
sẽ cung cấp hầu như không có thông tin trực tiếp trên (các) thẻ mà nó đại diện, nó sẽ chỉ trỏ đến nó / chúng. Bây giờ, ý tưởng tuyệt vời / điên rồ / ngu ngốc của tôi (bạn quyết định) là WholeCard thừa hưởng từ cả hai Card
và Representative
. Rốt cuộc, họ là những lá bài đại diện cho chính họ! WholeCards có thể thực hiện getRepresentative
như return this;
.
Về phần PartialCards
, họ không đại diện cho mình, nhưng họ có một bên ngoài Representative
không phải là một Card
, nhưng cung cấp các phương thức để truy cập hai PartialCard
s.
Tôi nghĩ hệ thống phân cấp kiểu này có ý nghĩa, nhưng nó phức tạp. Nếu chúng ta nghĩ về Card
s là "thẻ khái niệm" và Representative
s là "thẻ vật lý", thì hầu hết các thẻ đều có cả! Tôi nghĩ rằng bạn có thể đưa ra một lập luận rằng các thẻ vật lý thực tế có chứa các thẻ khái niệm và rằng chúng không giống nhau , nhưng tôi sẽ tranh luận rằng chúng là như vậy.
Sự cần thiết của đúc
Bởi vì cả hai PartialCard
và WholeCards
đều là Card
s, và thường không có lý do chính đáng để tách chúng ra, tôi thường chỉ cần làm việc với Collection<Card>
. Vì vậy, đôi khi tôi cần truyền PartialCard
s để truy cập các phương thức bổ sung của họ. Ngay bây giờ, tôi đang sử dụng hệ thống được mô tả ở đây vì tôi thực sự không thích diễn xuất rõ ràng. Và giống như Card
, Representative
sẽ cần phải được chuyển sang một WholeCard
hoặc Composite
, để truy cập vào thực tế Card
mà họ đại diện.
Vì vậy, chỉ để tóm tắt:
- Loại cơ sở
Representative
- Loại cơ sở
Card
- Loại
WholeCard extends Card, Representative
(không cần truy cập, nó đại diện cho chính nó) - Loại
PartialCard extends Card
(cung cấp quyền truy cập vào phần khác) - Loại
Composite extends Representative
(cung cấp quyền truy cập vào cả hai phần)
Đây có phải là điên rồ? Tôi nghĩ rằng nó thực sự có rất nhiều ý nghĩa, nhưng tôi thực sự không chắc chắn.