-1

I have a function named withColor() that is required to be called in class A and class B 's Snackbar class . I don't want to copy paste its code in each of this classes again and again.

fun Snackbar.withColor(@ColorInt colorInt:Int): Snackbar { this.view.setBackgroundColor(colorInt) return this }

This function is called in Snackbar usage of Class A and class B like this

class A bindinpercentproblemsFragment.radioGroup10Percentage?.setOnCheckedChangeListener(RadioGroup.OnCheckedChangeListener{ group, checkedId ->

        val isChecked = bindinpercentproblemsFragment.radioButton37Percentage.isChecked
        if (isChecked) {
            Snackbar.make(requireView(), "Correct", Snackbar.LENGTH_LONG)
                .withColor(Color.rgb(0, 128, 0))
                .show()

        } else {
            Snackbar.make(requireView(), "InCorrect", Snackbar.LENGTH_LONG)
                .withColor(Color.rgb(255, 0, 0))
                .show()
        }

    })

class B

  binding.radioGroup10HCF?.setOnCheckedChangeListener(RadioGroup.OnCheckedChangeListener{ group, checkedId ->

        val isChecked = binding.radioButton40HCF.isChecked
        if (isChecked) {
            Snackbar.make(requireView(), "Correct", Snackbar.LENGTH_LONG)
                .withColor(Color.rgb(0, 128, 0))
                .show()

        } else {
            Snackbar.make(requireView(), "InCorrect", Snackbar.LENGTH_LONG)
                .withColor(Color.rgb(255, 0, 0))
                .show()
        }

    })
klaus19
  • 23
  • 1
  • 10
  • Make the function public static? – smac89 Aug 23 '21 at 15:04
  • @smac89 `static` in Kotlin? [There is no `static` in Kotlin](https://stackoverflow.com/questions/40352684/what-is-the-equivalent-of-java-static-methods-in-kotlin)... – deHaar Aug 23 '21 at 15:07
  • "public static" is in Java, right? How can I implement it using Kotlin? – klaus19 Aug 23 '21 at 15:07
  • 3
    use companion in kotlin – because_im_batman Aug 23 '21 at 15:08
  • 1
    @deHaar Right! I meant companion objects. It's been a while since I did kotlin – smac89 Aug 23 '21 at 15:13
  • It really depends on the use case, though. Does it operate on the state of A or B's instances? Does it semantically belong more in A than in B or vice-versa? Or is it really just a helper that makes as much sense in A as in B? – Joffrey Aug 23 '21 at 15:18
  • Could you please add more details about your actual use case, this question cannot really be answered in general – Joffrey Aug 23 '21 at 15:24
  • Frame challenge: there's no need for a ‘fluent’ interface here.  `.apply{ setBackground(…) }` or whatever would work just as well, without needing any extra functions. – gidds Aug 23 '21 at 15:52
  • I'm even more confused now that you showed the code: you already have extracted what you needed into an extension function, you can simply put that extension anywhere that is accessible by both A and B. What exactly is your question then? – Joffrey Aug 23 '21 at 16:05
  • I don't want to copy the function withColor() in both these classes but write it only once and access it in both the classes. Actually, there are about 40 different Fragment classes that needs this function so copy pasting this function 40 times is bit redundant, isn't it? – klaus19 Aug 23 '21 at 16:16
  • So what's stopping you from calling this function from any of your Fragments? If it's defined outside a class, you can use it anywhere without copying it. – Tenfour04 Aug 23 '21 at 17:17
  • It isn't defined outside the class. I am trying to make a separate dedicated class just for this function but I am not understanding how to do it , do I need to make a Singleton class for it? – klaus19 Aug 23 '21 at 17:35
  • Finally I could do what I wanted :) I used companion object , Special thanks to Joffrey – klaus19 Aug 23 '21 at 17:50
  • @Rebecca since it's an extension function, you should just declare it at the top level, you don't need a wrapping class for it. Why do you want to put it in a class? – Joffrey Aug 23 '21 at 18:58
  • I don't understand what you mean by declare it at tope level. Are you telling me to write that function in every Fragment class where i need it rather than creating a wrapping class or something else. By help of companion object as you told me how to do in your previous comments now i am able to achieve what i wanted to achieve – klaus19 Aug 23 '21 at 19:05

1 Answers1

0

If this function operates on A and B's instance state, then you should probably move that common state into a parent (abstract) class, define that method in the parent class, and make A and B inherit from that parent class:

abstract class Parent {
    protected var commonState: Int = 42
    
    fun sharedMethodAffectingState() {
        commonState++
    }
}

class A : Parent() {
    fun doSomethingA() {
        sharedMethodAffectingState()
    }
}

class B : Parent() {
    fun doSomethingB() {
        sharedMethodAffectingState()
    }
}

If this function is stateless, then you still have multiple options.

If it is really semantically linked to A, and incidentally used in B, you may want to put it in A's companion object:

class A {
    companion object {
        fun someFunctionThatMakesSenseInNamespaceA()
    }
}

class B {
    fun doSomething() {
        A.someFunctionThatMakesSenseInNamespaceA()
    }
}

If the function is stateless and doesn't have a more obvious relation to A than to B, then it should probably live outside of both these classes. It could be a top-level function, a top-level extension function, or part of an object that serves as a namespace. But the choice here depends on what the function does and what makes the most sense semantically:

fun topLevel() { ... } // pollutes global namespace, use with case

fun SomeType.topLevelExtension() { ... } // OK if it acts on SomeType and makes sense globally

object SomeNamespace {

    fun sharedFunctionAccessibleGlobally() { ... }
}
Joffrey
  • 32,348
  • 6
  • 68
  • 100
  • I am using this function in two different fragments of class A and class B to display color of text message in my Android App – klaus19 Aug 23 '21 at 15:28
  • @Rebecca I'm not entirely sure what you mean still, it would really help if you edited your question with actual code. It seems that you're in a case where I would go for a top-level extension function on whatever type makes most sense to derive the color from, but with the smallest visibility possible to share it between A and B (if they are in the same file, you can make it `private`). – Joffrey Aug 23 '21 at 15:33
  • Thanks for helping me out. :) – klaus19 Aug 23 '21 at 17:51