3

What are some ways to obfuscate or limit access to public members of a class?

The motivation behind doing this is that I would like to be able to inline a method, but it needs access to other members in the class, which requires them to be public, however I would prefer these members to be anything but public, but since they must be public, I am looking for ways to obfuscate or limit access to them.

Here is an example of such a case where I would prefer preferablyPrivateLock to be private:

class SomeClass
{
    val preferablyPrivateLock = ReentrantLock()

    inline fun <R> fancyInlineFunction(function:()->R):R
    {
        preferablyPrivateLock.lock()
        try
        {
            return function()
        }
        finally
        {
            preferablyPrivateLock.unlock()
        }
    }
}

P.S. I know this seems like bad OO design; hope this question doesn't cost me any reputation...

Eric
  • 16,397
  • 8
  • 68
  • 76

2 Answers2

3

Here's a way to obfuscate access to preferablyPrivateLock with the help of extensions:

class SomeClass
{
    private val preferablyPrivateLock = ReentrantLock()
    val Unit.obfuscatedLock:ReentrantLock
        get() = preferablyPrivateLock

    inline fun <R> fancyInlineFunction(function:()->R):R
    {
        with(this) {Unit.obfuscatedLock}.lock()
        try
        {
            return function()
        }
        finally
        {
            with(this) {Unit.obfuscatedLock}.unlock()
        }
    }
}
Eric
  • 16,397
  • 8
  • 68
  • 76
2

The same can be done without Unit by having the method be an extension on its own class, in this case SomeClass. This simplifies the usage:

class SomeClass
{
    private val preferablyPrivateLock = ReentrantLock()
    val SomeClass.hiddenLock: ReentrantLock
        get() = preferablyPrivateLock

    inline fun <R> fancyInlineFunction(function:()->R):R
    {
        with(this) { hiddenLock }.lock()
        try
        {
            return function()
        }
        finally
        {
            with(this) { hiddenLock }.unlock()
        }
    }
}

class OtherClass {
    fun foo() {
        val x = SomeClass().hiddenLock // ERROR: Unresolved reference hiddenLock
    }
}

This solution was mentioned by @Kirill in Kotlin Slack. It is similar technique to this: In Kotlin, how do I add extension methods to another class, but only visible in a certain context?

Community
  • 1
  • 1
Jayson Minard
  • 84,842
  • 38
  • 184
  • 227