j2emanue
j2emanue

Reputation: 62519

Android Kotlin - How to make java builder setter methods

So I have already read this article but i don't think its completely what i want. I have an object that dagger is creating for me via constructor injection.

Lets start off in java what it looks like:

    public class AlgoliaSearchUsecase extends BaseUseCase {


    private final Index algoliaIndex;
    private final SearchRepository searchRepository;

    String query;
    int pageNum;

    @Inject
    public AlgoliaSearchUsecase(Index algoliaIndex, SearchRepository searchRepository, LoginRepository loginRepository) {
        super(loginRepository);
        this.algoliaIndex = algoliaIndex;
        this.searchRepository = searchRepository;
    }

    @Override
    protected Observable<AlgoliaSearchResultsModel> buildUseCaseObservable() {
        return searchRepository.fetchAlgoliaSearchResults(query,algoliaIndex,pageNum);
    }

//***THESE TWO SETTERS ARE KEY TO MY QUESTION **********
    public AlgoliaSearchUsecase setQuery(String query) {
        this.query = query;
        return this;
    }

    public AlgoliaSearchUsecase setPageNum(int pageNum) {
        this.pageNum = pageNum;
        return this;
    }
}

notice that the two setter methods return the object itself. It makes it convenient to write code like this:

//dagger will build this for me
@Inject AlgoliaSearchUsecase searchUseCase;

//... later on i can call its convenience methods like this:

searchUseCase
                .setQuery(query)
                .setPageNum(pageNum).
                execute(new DefaultSubscriber(){/.../};

Now i've converted the class AlgoliaSearchUsecase into a Kotlin class like this:

 class AlgoliaSearchUsecase @Inject
constructor(private val algoliaIndex: Index, private val searchRepository: SearchRepository, loginRepository: LoginRepository) : BaseUseCase(loginRepository) {

    internal var query: String = ""
    internal var pageNum: Int = 0

    override fun buildUseCaseObservable(): Observable<AlgoliaSearchResultsModel>? {
        return searchRepository.fetchAlgoliaSearchResults(query, algoliaIndex, pageNum)
    }

//i know i dont need these settings anymore but how can i still get the convence methods to return the object ?
    fun setQuery(query: String): AlgoliaSearchUsecase {
        this.query = query
        return this
    }

    fun setPageNum(pageNum: Int): AlgoliaSearchUsecase {
        this.pageNum = pageNum
        return this
    }
}

do i still have to keep these setter methods if i want the convenience methods (i.e. builder methods)? Remember dagger is creating this AlgoliaSearchUsecase for me by constructor injection so i dont have control of the constructor when im using it.

From the article provided it was mentioned i could do something like this:

val searchUseCase = AlgoliaSearchUsecase().apply{ query = "Ford"; pageNum = 2 }

but i am not in control of the constructor, dagger is. so i dont think i can do this. How can i still use the convenience methods in the setters like i did in java ?

Upvotes: 2

Views: 711

Answers (1)

s1m0nw1
s1m0nw1

Reputation: 81879

This is actually pretty easy with the use of apply, which does exactly what you need: take a block of action and return the instance afterwards:

fun setQuery(query: String) = apply {
    this.query = query
}

fun setPageNum(pageNum: Int)  = apply {
    this.pageNum = pageNum
}

Also see this answer.

Upvotes: 2

Related Questions