Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Apply software principles to android development

Apply software principles to android development

Apply software principles to android development

Orhan Obut

May 12, 2015
Tweet

More Decks by Orhan Obut

Other Decks in Technology

Transcript

  1. • displayLogin • displayRegistration • displayHome AuthActivity • displayRegistration •

    makeLoginRequest • displayHome LoginFragment • displayLogin • makeRegistrationRequest • displayHome RegistrationFragment
  2. Entities should have only one responsibility. Responsibility is “a reason

    for change”. Single responsibility Entities should have only one
  3. public class LoginFragment extends Fragment { void onLoginClicked() void makeLoginRequest()

    void displayHome() void onRegisterClicked() void displayRegistration() }
  4. AuthActivity • displayLogin() • makeLoginRequest() • parseToUser() • makeRegisterRequest() •

    displayHome() • onLoginClicked() • onRegisterClicked() • onRegisterClicked() • onLoginClicked() LoginFragment RegistrationFragmentt
  5. public class AuthActivity extends Activity { void onLoginClicked(){} void makeLoginRequest(){

    HttpPost httpPost = new HttpPost(URL); HttpClient client = new DefaultHttpClient(); HttpResponse response = client.execute(httpPost); } User parseToUser(String json){ JSONObject jsonObject = new JSONObject(content); String name = jsonObject.getString("name"); } void displayHome(){} void onRegisterClicked(){} void displayRegistration(){} }
  6. • displayLogin() • displayRegistration() • displayHome() • onLogin() AuthActivity ApiManager

    • login() • register() • parseToUser() public class ApiManager { void login(Callback callback){} User parseToUser(String content){} void register(Callback callback){} } public class AuthActivity extends Activity { ApiManager apiManager = new ApiManager(); void onLogin(){ apiManager.login(callback); } }
  7. ApiManager • login() • register() • parseToUser() public class ApiManager

    { void login(Callback callback){ ... User user = parseToUser(json); } User parseToUser(String content) { JSONObject jsonObject = new JSONObject(content); String name = jsonObject.getString("name"); return new User(name); } }
  8. public class ApiManager { Gson gson = new Gson(); void

    makeLoginRequest(Callback callback){ ... User user = gson.fromJson(json, User.class); } } ApiManager • login() • register() Gson • toJson() • fromJson()
  9. Close for modification but how? • Use abstraction (stay tuned)

    • Make all variables private • Avoid global variables as much as possible
  10. public class MyView extends View { boolean editMode; @Override public

    void setBackgroundColor(int color) { if (editMode) { super.setBackgroundColor(Color.WHITE); return; } super.setBackgroundColor(color); } } for (View view : views) { view.setBackgroundColor(Color.BLACK); }
  11. public class MyView extends View { boolean editMode; @Override public

    void setBackgroundColor(int color) { super.setBackgroundColor(color); } public void setBackground(int color) { if (editMode) { super.setBackgroundColor(Color.WHITE); return; } super.setBackgroundColor(color); } }
  12. class ImageActivity extends Activity { @Override public void onCreate(Bundle bundle)

    { super.onCreate(savedInstance); // init some variables } @Override public void onDestroy() { // free some memory } public void showGalery() public void dismissGalery() public void takePhoto() } class AccountActivity extends ImageActivity { @Override public void onCreate(Bundle bundle) { // init } public void onAvatarClicked() { showGalery(); } public void onTakePhotoClicked() { takePhoto(); } }
  13. public class ProductActivity extends ImageActivity { @Override public void onCreate(Bundle

    bundle) { // init } public void onNewPhotoClicked() { showGalery(); } public void onTakePhotoClicked() { takePhoto(); } }
  14. class ShareActivity extends BaseActivity { @Override public void onCreate(Bundle bundle)

    { // init some fields } public void showGalery() {} public void dismissGalery() {} } class ProductListActivity extends ShareActivity { @Override public void onCreate(Bundle bundle) { // init } public void onShareClicked() { showGalery(); } public void onDismissClicked() { dismissGalery(); } }
  15. class ImageActivity extends BaseActivity { @Override public void onCreate(Bundle bundle)

    { super.onCreate(savedInstance); // init some variables } @Override public void onDestroy() { // free some memory } public void showGalery(){} public void dismissGalery(){} public void takePhoto(){} } class ShareActivity extends BaseActivity { @Override public void onCreate(Bundle bundle) { // init some fields } public void showGalery() {} public void dismissGalery() {} }
  16. class ImageHelper { void onCreate() void onDestroy() void showGalery() void

    dismissGalery() void takePhoto() } class AccountActivity extends BaseActivity { ImageHelper imageHelper; @Override public void onCreate(Bundle bundle){ imageHelper.onCreate(); } @Override public void onDestroy() { imageHelper.onDestroy(); } public void onAvatarClicked() { imageHelper.showGalery(); } public void onTakePhotoClicked() { imageHelper.takePhoto(); } }
  17. public class ImageHelper { public void onCreate() public void onDestroy()

    public void showGalery() public void dismissGalery() public void takePhoto() } public class ShareHelper { public void onCreate() public void showGalery() public void dismissGalery() } class ShareAndImageActivity extends BaseActivity { ImageHelper imageHelper; ShareHelper shareHelper; @Override public void onCreate(Bundle bundle) { ... imageHelper.onCreate(); shareHelper.onCreate(); } public void onGaleryClicked() { imageHelper.showGalery(); } public void onShareClicked() { shareHelper.showGalery(); } }
  18. AuthActivity LoginFragment LoginListener class AuthActivity extends Activity implements LoginListener {

    @Override public void onLogin(){ apiManager.login(); } @Override public void onRegister() { apiManager.register(); } } interface LoginListener { void onLogin(); void onRegister(); } class LoginFragment extends Fragment { LoginListener listener; void onLoginClicked() { listener.onLogin(); } void onRegisterClicked() { listener.onRegister(); }
  19. LoginFragment AuthActivity class AuthActivity extends Activity implements LoginListener { @Override

    public void onLogin(){ apiManager.login(new Callback(){ @Override public void onSuccess(){ LoginFragment fragment = (LoginFragment) getFragmentManager() .findFragmentByTag("LoginFragment"); fragment.addItems(items) } }); } }
  20. Api Manager Auth Activity public class AuthActivity extends Activity {

    ApiManager apiManager = new ApiManager(); void login(){ apiManager.login(callback); } }
  21. Api Manager Auth Activity Api Service public class AuthActivity {

    ApiService api = new ApiManager(); void login(){ api.login(callback); } } interface ApiService { void login(); void register(); } class ApiManager implements ApiService{ Gson gson = new Gson(); @Override public void login() {} @Override public void register() {} }
  22. Gson Api Manager public class ApiManager implements ApiService { Gson

    gson = new Gson(); @Override public void login() { ... User user = gson.fromJson(body, User.class); } @Override public void register() {} }
  23. Gson Api Manager Parser class ApiManager implements ApiService { Parser

    parser = new GsonParser(); @Override public void login() { ... parser.fromBody(data, User.class); } @Override public void register() {} } public interface Parser { String toBody(...); <T> T fromBody(...); } class GsonParser implements Parser { Gson gson = new Gson(); @Override String toBody(...) { gson.toJson(object); } @Override <T> T fromBody(...){ gson.fromJson(body, type); } }
  24. Login Fragment ApiManager GsonParser Registration Fragment Home Fragment Home Activity

    Base Activity Auth Activity Api Service Parser Home Listener Registration Listener Login Listener
  25. class ApiManager implements ApiService { Parser parser; public ApiManager(Parser parser){

    this.parser = parser; } } public class AuthActivity extends Activity { ApiService apiService = new ApiManager(new GsonParser); void login(){ apiService.login(callback); } }
  26. public interface LoginListener { void onLogin(); void onRegister(); void onUsernameTextChanged();

    } public class AuthActivity extends BaseActivity implements LoginListener { @Override public void onLogin(){} @Override public void onRegister(){} @Override public void onUsernameTextChanged() { showToastMessage(); } }
  27. public class AccountActivity extends BaseActivity implements LoginListener { @Override public

    void onLogin(){} @Override public void onRegister(){} @Override public void onUsernameTextChanged() { } }
  28. class LoginFragment extends Fragment { TextListener textListener; void setTextListener(TextListener listener)

    { textListener = listener; } public interface LoginListener { void onLogin(); void onRegister(); } public interface TextListener { void onUsernameTextChanged(); } } class AccountActivity extends Activity implements LoginFragment.LoginListener, LoginFragment.TextListener { public void displayLogin() { LoginFragment f = new LoginFragment(); f.setTextListener(this); ... } @Override public void onLogin(){} @Override public void onRegister(){} @Override public void onUsernameTextChanged(){} }
  29. public class HomeActivity extends Activity { private static final String

    KEY_USER = "KEY_USER"; void something() { intent.putExtra(KEY_USER, user); } } public class HomeFragment extends Fragment { private static final String KEY_USER = "KEY_USER"; void something() { User user = intent.getParcelableExtra(KEY_USER); } } Create the same keys in each class
  30. public class HomeActivity extends Activity { public static final String

    KEY_USER = "KEY_USER"; void something() { intent.putExtra(KEY_USER, user); } } public class HomeFragment extends Fragment { void something() { User user = intent.getParcelableExtra(HomeActivity.KEY_USER); } } Make the keys public
  31. public class Constants { public static final String KEY_USER =

    "KEY_USER"; } public class HomeActivity extends Activity { void something() { intent.putExtra(Constants.KEY_USER, user); } } public class HomeFragment extends Fragment { void something() { User user = intent.getParcelableExtra(Constants.KEY_USER); } } Put all keys to a class
  32. public class HomeActivity extends Activity { private static final String

    KEY_USER = "KEY_USER"; public static Intent newIntent(Context context, User user) { Intent intent = new Intent(context, HomeActivity.class); intent.putExtra(KEY_USER, user); return intent; } @Override public void onCreate(Bundle bundle) { User user = getIntent().getParcelableExtra(KEY_USER); } } public class LoginActivity extends Activity { void displayHome() { startActivity( HomeActivity.newIntent(this, user); ); } void displayLogin() { … LoginFragment.newFragment(foo); } }
  33. public class User { private Account account; public Account getAccount(){

    return account; } } public class Account { private Image image; private Credentials credentials; public Image getImage(){ return image; } public Credentials getCredentials() { return credentials; } } public MainActivity { User user; private void initAvatar() { Image image = user.getAccount().getImage(); } }
  34. • Each unit should only talk to its friends •

    Don't talk to strangers. Law of Demeter
  35. class User { private final Account account; public Image getAvatar(){

    if (account == null){ return null; } return account.getImage(); } } public MainActivity extends Activity { User user; private void initAvatar() { Image image = user.getAvatar(); } }
  36. Single Responsibility Liskov’s Substitution Interface Segregation Open/Closed Dependency Inversion Dependency

    Injection Composite High Cohesion Loose Coupling Static Factory Method Law of Demeter