as we know,in many OO program language ,we can use some access modifiers to specify the access scope of the fields inside an object .
for example, in java we can use public,protected or private to specify the access scope of a field ,for all of the caller to this object .
but my question is that ,I want to specify different access permissions of a callee , for different callers.
the most important point is: the caller class could be written by other programmers, but after my main program is written, they can not change the permission by their own implementation.
for example ,suppose there are at least 3 entities in the chess game program, 1 chessboard and 2 players , I want let the Black side player have "read" access right to all of the chess on the chessboard,but just "move" access access right to all of the black chess,(and only have "move" right when it's in his turn) , and vice versa .
I have already had some ideas as below,but It seems that these ideas are too complicated and not ideal.
so is there any good approach、design pattern,or something else to deal with this problem ?
many thanks
//===============================================================
my ideas:
1.use access key class.
2.use mediate controller class
(although I can use some if-else in this sub-class to decide it can move some chess or not ,but I want let the player class be written by other programer,and let them write their AI,so the permission judgement flow used by these sub-class can not be used directly in the player class as a approach for my question.)
3.low level approach(ugly and not ideal)
in "move" or "read" method of the board class,check the callstack of the thread ,to know is the caller belong to the class "player", and which side(black or white) it is.
//===================================================================
any better idea? thank you
No matter how you set this up, you have the option of by passing it with reflection or native code.
The only safe way is to have the components run in their own process so they have no direct access to each other. They can run as services, filtering who is accessing them and limit what operations can be performed. Even this is not completely secure.
However, if you use an access key via a method call you are assuming a level of trust. If you are willing to assume a level of trust then perhaps you could consider a simpler model. i.e. I am not sure what level of trust an access key would be the right amount of security.
a design pattern or approach to handle access control of the fields of an object
Every type specifies access control to fields and methods via private
, protected
, public
or package only. Another class can only call methods or get field values if it has access to another object - a reference. Thus you must control who can get a reference of some object.
Even if a proxy is often a solution to control access you can also make access right rules explicit by design.
For the chess game I would first design an interface called ChessPiece
. Since every player can see all chesss pieces I would specify a method that returns the position of a chess piece.
public interface ChessPiece {
public Position getPosition();
}
All chess pieces are placed on a chessboard. So the next step is to design a chessboard that gives access to all ChessPiece
s.
public interface Chessboard {
public Collection<ChessPiece> getChessPieces();
}
A Player
has access to the chessboard and thus can see all pieces. But a Player
is only allowed to move his own pieces. Thus a Player
must have access to a special kind of chess piece.
public class Player {
private Collection<PlayersChessPiece> ownPieces;
private Chessboard chessboard;
public Player(Chessboard chessboard, Collection<PlayersChessPiece> ownPieces){
this.chessboard = chessboard;
this.ownPieces = ownPieces;
}
}
Since a player can only move his own chess pieces I put this aspect into the design.
public interface PlayersChessPiece extends ChessPiece {
public void move(Position position) throws MoveNotSupported;
}
The idea behind this design is simple. A method belongs to a class and an object is an instance of some class. Someone can only call a method if one has access to an object (a reference). Thus access rights can be simply represented by objects that put an access right perspective on other objects. You only have to make sure that the correct reference is given to a client.
Of course someone can hack objects and access private fields using reflection. You can only prevent this by installing a security manager.
Proxy is what you need.
This design pattern is controlling access to a specific object, can control their creation or anything.
Best part about it is that client has no idea that he is using a proxy. Only part is if client calls method that it has no access of you can throw some exception. In this case you have to modify class interface for each such method to be throwing exception, actual implementation wont do it, but for the sake of proxy this is good solution.
Reference
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With