Table of Contents
Common Design Patterns for Android. Summary.
This is a summary of the Common Design Patterns for Android article.
- Creational patterns: how you create objects.
- Builder
- Dependency Injection
- Singleton
- Structural patterns: how you compose objects.
- Adapter
- Facade
- Behavioral patterns: how you coordinate object interactions.
- Command
- Observer
- Model View Controller
- Model View ViewModel
Creational Patterns
Builder
Example : AlertDialog
new AlertDialog.Builder(this) .setTitle("Metaphorical Sandwich Dialog") .setMessage("Metaphorical message to please use the spicy mustard.") .setNegativeButton("No thanks", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { // "No thanks" button was clicked } }) .setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { // "OK" button was clicked } }) .show();
Dependency Injection
Dagger 2 is the most popular open-source dependency injection framework for Android and was developed in collaboration between Google and Square. …
TODO: Learn more about dependency injection
Singleton
public class ExampleSingleton { private static ExampleSingleton instance = null; private ExampleSingleton() { // customize if needed } public static ExampleSingleton getInstance() { if (instance == null) { instance = new ExampleSingleton(); } return instance; } }
Structural Patterns
Adapter
public class TribbleAdapter extends RecyclerView.Adapter { private List mTribbles; public TribbleAdapter(List tribbles) { this.mTribbles = tribbles; } @Override public TribbleViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext()); View view = inflater.inflate(R.layout.row_tribble, viewGroup, false); return new TribbleViewHolder(view); } @Override public void onBindViewHolder(TribbleViewHolder viewHolder, int i) { viewHolder.configure(mTribbles.get(i)); } @Override public int getItemCount() { return mTribbles.size(); } }
Facade
The Facade pattern provides a higher-level interface that makes a set of other interfaces easier to use. Example: Retrofit
Behavioral Patterns
Command
Command pattern lets you issue requests without knowing the receiver. You encapsulate a request as an object and send it off; deciding how to complete the request is an entirely separate mechanism.
Example: EventBus
Observer
The Observer pattern defines a one-to-many dependency between objects. When one object changes state, all of its dependents are notified and updated automatically.
Example: RxAndroid
Model View Controller
- Model: your data classes. If you have User or Product objects, these “model” the real world.
- View: your visual classes. Everything the user sees falls under this category.
- Controller: the glue between the two. It updates the view, takes user input, and makes changes to the model.
Model View ViewModel
This unfortunately-quite-confusingly-named architectural pattern is similar to the MVC pattern; the Model and View components are the same. The ViewModel object is the “glue” between the model and view layers, but operates differently than the Controller component. Instead, it exposes commands for the view and binds the view to the model. When the model updates, the corresponding views update as well via the data binding. Similarly, as the user interacts with the view, the bindings work in the opposite direction to automatically update the model. This reactive pattern removes a lot of glue code.
- Interesting (small) article about ViewModel: https://nathan79c.hashnode.dev/introduction-to-viewmodel-simplifying-communication-between-view-and-data
- Layers:
- Data Layer
- databases, API calls etc
- View Layer
- UI
- Domain Layer
- “business logic”
- ViewModel is a glue between Data Layer and View Layer
- ViewModel has 2 primary functions
- Expose Data to the View
- Handle User Events
- callin APIs, retrieving/saving data etc
- Best practices:
- Avoid storing UI elements (activities, fragments, contexts etc)
- ⇒ memory leaks
- Use LiveData or StateFlow as types for ViewModels
- logic for data interaction should be handled by ViewModel
