Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin pattern construction with different parameters

Here is my dilemma.

1) I want to create instances of different classes depending on a single parameter --> Solution : Factory Pattern. The nice thing about Factory is zero parameter constructor.

2) Each of these classes have different constructors. For example

class PhotosProviderFacebook(val refActivity: WeakReference<Activity>)

class PhotosProviderLocal(val context: Context, val loaderManager: LoaderManager) 

I thought about Builder Pattern. See how Builder pattern is done in Kotlin

Is there a design pattern that respect these constraints ?

1) First build an instance depending on a parameter. Possibly without passing yet the constructor inputs.

2) Pass parameters in constructor

Factory + Builder are just an idea. Maybe there is a simpler way.

like image 951
Raymond Chenon Avatar asked Jun 27 '26 22:06

Raymond Chenon


1 Answers

You probably might want to use a strategy pattern in combination with good old polymorfism

First, you can add an abstract class to your concrete classes

abstract class PhotosProvider

class PhotosProviderFacebook(val params: CreationParamsFacebook): PhotosProvider()

class PhotosProviderLocal(val params: CreationParamsLocal): PhotosProvider()

Then, you can do the same for the parameters, that may change depending on the class (I used Strings instead of your classes for simplicity and to make it compile)

abstract class CreationParams

class CreationParamsFacebook(val refActivity: String): CreationParams()

class CreationParamsLocal(val context: String, val loaderManager: String): CreationParams()

Now, I code the strategy pattern for each creation method (see how I can safely cast to the correct parameters for each class with as)

abstract class PhotosProviderCreationStrategy {
    abstract fun create(params: CreationParams) : PhotosProvider
}

class PhotosProviderFacebookCreationStrategy: PhotosProviderCreationStrategy() {
    override fun create(params: CreationParams): PhotosProvider {
        return PhotosProviderFacebook(params as CreationParamsFacebook)
    }
}

class PhotosProviderLocalCreationStrategy: PhotosProviderCreationStrategy() {
    override fun create(params: CreationParams): PhotosProvider {
        return PhotosProviderLocal(params as CreationParamsLocal)
    }
}

Finally, in order to redirect to the correct strategy I use a map with a specific type. You may also create an abstration that includes the type and the abstract params (which can be easily be converted with Jackson if you receive the date from a web service)

enum class CreationType {
    FACEBOOK_PROVIDER, LOCAL_PROVIDER
}

class PhotosProviderCreator(
    private val strategies: HashMap<CreationType, PhotosProviderCreationStrategy> = hashMapOf(
        CreationType.FACEBOOK_PROVIDER to PhotosProviderFacebookCreationStrategy(),
        CreationType.LOCAL_PROVIDER to PhotosProviderLocalCreationStrategy())
) {
    fun create(creationType: CreationType, creationParams: CreationParams): PhotosProvider {
        return strategies[creationType]?.create(creationParams)?: 
        throw RuntimeException("Strategy not found for type: $creationType")
    }
}
like image 62
Sebastian D'Agostino Avatar answered Jun 30 '26 10:06

Sebastian D'Agostino



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!