簡體   English   中英

如何限制java中兩個類之間的訪問權限?

[英]How to restrict access privilege between two classes in java?

我有兩個類PlayerGame

public class Player {
    private List<String> cards;

    public Player(){
        cards = new ArrayList<String>();
    }
}
public class Game {
    List<Player> players;

    public Game(List<Player> players){
        this.players = new ArrayList<Player>();

        for(Player player: players){
            this.players.add(player);
        }

    }

    private void distributeCards(){
        ...

    }

    public void start(){
        distributeCards()
        ...

    }

}

Game class的distributeCards方法需要修改玩家object的cards屬性。 如果我為此在 Player class 中聲明一個公共或受保護的方法,則同一 package 中的其他類也將擁有特權,但我不希望那樣。 在這種情況下我該怎么辦?

如果我違反了設計原則或設計模式的任何規則,請告訴我。

游戲class的distributeCards方法需要修改玩家object的cards屬性。

一個 class 不應修改另一個 class 的屬性。 這打破了封裝原則。

相反, Player object 應該聲明Game object 可以調用的public方法。 例如,您可以將public giveCard(Card card)添加到Player class 以模擬將單張卡片交給玩家。 然后Player class 決定如何處理Card object。 例如,它可以將其插入cards列表。

請注意,在此交互中, Game object 不知道cards列表。 它只知道Player有一個可以調用的名為giveCard()的方法。

我會考慮的事情,假設Player必須以某種方式公開卡片列表:

  • 也許,在您的設計和實現中,卡片不是玩家的財產,而是游戲的財產; 例如:

     public class Game { List<Player> players; Map<Player, List<String>> cards;

    如果只有Game想知道卡片列表,或者系統的 rest 可以向Game詢問特定Player的卡片列表,這將起作用。

  • 也許Game負責提供Player對象,因此它可以訪問其內部 state。 Player可以是Game負責提供私有內部 class 的接口。 或者Player是一個不可變的 class,由Game構建,帶有一張卡片列表。

    處理此選項的另一種方法是認為“玩家”實際上是游戲中的用戶。 因此, Game獲取將要玩的用戶列表並將其轉換為Player對象列表。 Game負責Player object 中的卡片列表。

  • 一個giveCard(Card)方法就像 Code-Apprentice 寫的一樣。 這意味着您重新考慮您的約束並允許每個人修改Player 此外,您甚至可以創建一個方便的方法giveCards(List<Card>) ,其中Player將卡片列表參數復制到其內部 state 中。 這樣,任何外人都無法直接修改Player的內部 state。

    作為對此選項的修正,您可以將驗證邏輯添加到giveCards(List<Card>)方法,例如,如果Player已經有卡片,它會拋出IllegalStateException 這里的缺點是這種行為在 class 的設計中並不明顯。

  • 您可以將卡片分發的邏輯移至Player 因此,例如, Game將牌洗牌並將洗牌后的列表提供給第一個Player Player選擇一些卡片,將它們移動到其內部 state 並將它們從洗牌列表中刪除; Game將剩余的牌交給下一位Player 這並不總是合適的,你根據你的設計來判斷。

  • 在我自己的紙牌游戲實驗中,設計是GamePlayerCardHandPlayer的牌列表)等是持有游戲當前 state 的不可變值對象。 (提示:查看Immutables 。)另一個 class,比如GameEngine ,負責獲取 state 並返回一個的不可變 state 以響應用戶或游戲操作。 Game是根state object,其他一切都可以通過它到達。 例如:

     public class GameEngine { public Game distributeCards(Game game) {... } }

    如果需要,您可以將業務邏輯方法添加到Game class,這里的要點是不變性,並且每個操作都返回一個新的 state。 想想 Redux 為 Java :)

您可以添加更新播放器 object 的方法並將其public 讓我舉個例子:

public class Player {
    private List<String> cards;

    public Player(){
        cards = new ArrayList<String>();
    }

    public updateCards(string card) {
       // ... other code is omitted for the brevity
      
    }
}

為什么我們需要創建這樣的方法?

更新:

我無法在播放器 class 中添加公共或受保護方法來這樣做,我已經在問題中描述了原因

有四種類型的 Java 訪問修飾符

  • 私有:私有修飾符的訪問級別僅在 class 內。 不能從 class 外部訪問它。

  • 默認值:默認修飾符的訪問級別僅在 package 內。 不能從 package 外部訪問它。 如果您不指定任何訪問級別,它將是默認值。

  • 受保護:受保護修飾符的訪問級別在 package 之內和 package 之外(通過子 class)。 如果不創建子 class,則無法從 package 外部訪問它。

  • 公共:公共修飾符的訪問級別無處不在。 可以從 class 內部、class 外部、package 內部和 ZEFE90A8E6004A7C840DZDZF6788 外部訪問它。

如果您不能使用publicprotected的訪問修飾符,那么您需要重新考慮這些為什么您不能使用上述訪問修飾符的原因。

OOP 建議使用封裝

封裝是指將數據與操作該數據的方法捆綁在一起,或限制對對象的某些組件的直接訪問

假設我們出現在 100 年前。 你有一輛帶蒸汽機的汽車。 作為司機,您需要了解汽車的所有數據,例如蒸汽鍋爐的工作原理,您需要將煤放入發動機,檢查蒸汽鍋爐的溫度。

現在讓我們想象一下我們有現代汽車。 事實上,車並沒有改變。 我們必須給汽車加油,曲軸轉動車輪。 但進步在於不同的領域。 所有這些操作都對用戶隱藏。 但它允許駕駛汽車而不用考慮它是如何工作的,發動機會發生什么。 隱藏細節允許任何用戶使用汽車。 您不必成為擁有 20 年經驗的機械師。 這種隱藏在 OOP 中稱為封裝。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM