About Monkey 2 › Forums › Monkey 2 Code Library › Using 'private facades' to accessing protected members
Tagged: coding trick
This topic contains 2 replies, has 2 voices, and was last updated by
nerobot 1 year, 7 months ago.
-
AuthorPosts
-
September 7, 2017 at 11:10 am #10314
Working on component-based system I found a nice solution to access to protected code. So I can leave it protected not public for end user. So…
Explain by example.
Let’s we have a class named Component.
Monkey1234567891011121314Class ComponentProperty gameObject:GameObject()Return _gameObjectEndProtectedField _gameObject:GameObjectNethod New()' constructor is protected tooEndEnd- Each component must be associated with game object.
- We have to get access to game object but not change it directly
- So public field or property isn’t good here
Solution is using ‘private facade’ / bridge class to get acces to protected members.
- Private – means private section of a file, not a class
- Bridge should extends our needed class, so worked for non-final classes only
Let’s write such bridge
Monkey1234567891011121314151617181920212223242526272829303132333435' file GameObject.monkey2Class GameObjectMethod AddComponent<T>:T() Where T Extends ComponentLocal comp:=ComponentBridge_Go.NewComponent<T>()Local name:=Typeof( comp ).Name_components[name]=compComponentBridge_Go.SetGameObject( comp,Self )Return compEndEndPrivate' make it abstact to deny instantiationClass ComponentBridge_Go Extends Component AbstractFunction NewComponent<T>:T() Where T Extends ComponentReturn New T ' protected constructorEndFunction SetGameObject( comp:Component,go:GameObject )comp._gameObject=go ' protected field'comp.OnAttached()EndEndWe can’t get access to our Bridge‘s classes outside framework – them are private in files.
And we able to provide clean api for end users.
September 12, 2017 at 9:22 pm #10436Is this an actual design pattern?
I tried to make a simple example to understand it better.
Monkey1234567891011121314151617181920212223#Import "<std>"Using std..Class MessageProperty Content:String()Return _contentEndProtectedField _content:StringEndClass MessageChanger Extends Message AbstractFunction Set(message:Message, content:String)message._content = contentEndEndFunction Main()Local m := New MessageMessageChanger.Set(m, "Hello World")Print(m.Content)EndI had this question for quite some time, how to control the access of class contents by certain restrictions, this seems to do the trick nicely. However the only bummer -as I think of it- is that the Changer class needs to inherit from the actual object, I hope that there won’t be any problem with creating such inheritance.
September 13, 2017 at 1:35 am #10437Limitation is – you can’t inherit if class is final.
In my case I want to access to protected but somewhere in inner scope. So I put such bridges to private section.
Also there is an Internal keyword that we can use inside of our modules to access private sections. Like friend keyword in c++.
-
AuthorPosts
You must be logged in to reply to this topic.