abyanhmd / github-user-app

0 stars 0 forks source link

Separation of Concerns Violation #3

Open abyanhmd opened 1 year ago

abyanhmd commented 1 year ago

Calling APIs directly from a view class violates the principle of separation of concerns. This flaw occurs when the responsibility of handling network communication and data-fetching logic is mixed with the UI-related tasks within the view class. It can lead to code that is difficult to maintain, test, and understand.

class FollowingFragment : Fragment() {
    // Rest of the codes
    private fun displayFollowing(username: String) {
        showLoading(true)
        Log.d(TAG, "displayFollowing: ")

        val client = RetrofitConfig.getUserService().getUserFollowing(username)
        client.enqueue(object : Callback<List<FollowingResponse>> {
            override fun onResponse(
                call: Call<List<FollowingResponse>>,
                response: Response<List<FollowingResponse>>
            ) {
                showLoading(false)
                if (response.isSuccessful) {
                    val responseBody = response.body()

                    if (responseBody != null) setFollowing(responseBody)

                    Log.d(TAG, "onResponse: ${responseBody.toString()}")
                } else {
                    Log.e(TAG, "onFailure: ${response.message()}")
                }
            }

            override fun onFailure(call: Call<List<FollowingResponse>>, t: Throwable) {
                showLoading(false)
                Log.e(TAG, "onFailure: ${t.message}")
            }
        })
    }

    // Rest of the codes.
}

It is better to follow architectural patterns like MVVM (Model-View-ViewModel) or MVP (Model-View-Presenter). These patterns separate the UI logic from the data-fetching operations, improving code organization, testability, and maintainability.


This code has the problem like in the FollowingFragment.kt.

class FollowersFragment : Fragment() {
    // Rest of the codes
    private fun displayFollowers(username: String) {
        showLoading(true)

        val client = RetrofitConfig.getUserService().getUserFollowers(username)
        client.enqueue(object : Callback<List<FollowersResponse>> {
            override fun onResponse(
                call: Call<List<FollowersResponse>>,
                response: Response<List<FollowersResponse>>
            ) {
                showLoading(false)
                if (response.isSuccessful) {
                    val responseBody = response.body()

                    if (responseBody != null) setFollowers(responseBody)

                    Log.d(TAG, "onResponse: ${responseBody.toString()}")
                } else {
                    Log.e(TAG, "onFailure: ${response.message()}")
                }
            }

            override fun onFailure(call: Call<List<FollowersResponse>>, t: Throwable) {
                showLoading(false)
                Log.e(TAG, "onFailure: ${t.message}")
            }
        })
    // Rest of the codes.
    }


 private fun searchUser() {
        showLoading(true)

        val client = RetrofitConfig.getUserService().getUsers(USERNAME)
        client.enqueue(object : Callback<UserResponse> {
            override fun onResponse(call: Call<UserResponse>, response: Response<UserResponse>) {
                showLoading(false)
                if (response.isSuccessful) {
                    val responseBody = response.body()
                    if (responseBody != null) {
                        setUser(responseBody.items)
                    }
                } else {
                    Log.e(TAG, "onFailure: ${response.message()}")
                }
            }

            override fun onFailure(call: Call<UserResponse>, t: Throwable) {
                showLoading(false)
                Log.e(TAG, "onFailure: ${t.message}")
            }
        })
    }
LidiaIvanova commented 1 year ago

This is correct. 0,9 points