在Android开发中,设计模式是非常重要的一个方面。它们为开发人员提供了一种可复用、可维护和可扩展的解决方案,许多常见的问题已经有了设计模式的解决方案。在本篇文章中,将会介绍在Android开发中常用的设计模式及其应用场景。
一、单例模式
单例模式是一种经典的设计模式,它确保了一个类在任何情况下都只能有一个实例,并提供了一个全局访问点来访问该实例。
在Android开发中,单例模式通常用于管理应用程序的全局状态,例如:应用程序的配置信息、网络连接对象、数据库连接对象等。
下面是单例模式的示例代码:
public class Singleton { private static volatile Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
在该示例代码中,该类的构造函数被声明为私有的,防止在类外部创建它的实例。在getInstance()方法中,使用double-check locking方式来确保只有在instance为空的情况下才创建对象,并使用volatile修饰符确保线程安全性。
二、观察者模式
观察者模式是一种行为型模式,它定义了一种一对多的依赖关系,使得多个观察者对象可以同时监听一个主题对象的状态变化。
在Android开发中,观察者模式通常用于实现UI的数据更新,例如当一个数据模型的状态发生变化时,所有观察该模型的界面可以同时更新。
下面是观察者模式的示例代码:
public interface Observer { void onUpdate(Observable observable); } public interface Observable { void addObserver(Observer observer); void removeObserver(Observer observer); void notifyObservers(); } public class DataModel implements Observable { private Listobservers = new ArrayList<>(); private int data; public int getData() { return data; } public void setData(int data) { if (this.data != data) { this.data = data; notifyObservers(); } } @Override public void addObserver(Observer observer) { observers.add(observer); } @Override public void removeObserver(Observer observer) { observers.remove(observer); } @Override public void notifyObservers() { for (Observer observer : observers) { observer.onUpdate(this); } } } public class MainActivity implements Observer { @Override public void onUpdate(Observable observable) { if (observable instanceof DataModel) { DataModel dataModel = (DataModel) observable; // Update UI with new data } } }
在该示例代码中,DataModel实现了Observable接口,MainActivity实现了Observer接口。当DataModel中的data属性发生变化时,DataModel会调用notifyObservers()方法通知所有观察者,包括MainActivity。然后MainActivity可以在onUpdate()方法中更新UI来反映数据的变化。
三、策略模式
策略模式是一种行为型模式,它定义了一系列算法,将每个算法都封装起来,并且使它们可以互换。策略模式让算法的变化独立于使用它的客户端。
在Android开发中,策略模式通常用于实现复杂算法或业务逻辑,例如:在表单中实现输入验证或者在计算器应用中实现计算功能。
下面是策略模式的示例代码:
public interface CalculationStrategy { int calculate(int num1, int num2); } public class AddStrategy implements CalculationStrategy { @Override public int calculate(int num1, int num2) { return num1 + num2; } } public class SubtractStrategy implements CalculationStrategy { @Override public int calculate(int num1, int num2) { return num1 - num2; } } public class Calculator { private CalculationStrategy strategy; public Calculator(CalculationStrategy strategy) { this.strategy = strategy; } public int calculate(int num1, int num2) { return strategy.calculate(num1, num2); } public void setStrategy(CalculationStrategy strategy) { this.strategy = strategy; } } // Usage example Calculator calculator = new Calculator(new AddStrategy()); int result = calculator.calculate(5, 3); calculator.setStrategy(new SubtractStrategy()); result = calculator.calculate(5, 3);
在该示例代码中,AddStrategy和SubtractStrategy类都实现了CalculationStrategy接口,分别实现了加法和减法的算法。Calculator类使用构造函数来接收一个CalculationStrategy实例,并在calculate()方法中调用该实例的calculate()方法来实现具体的算法。然后,该类提供了一个setStrategy()方法,可以在运行时动态地更改算法。
四、建造者模式
建造者模式是一种创建型模式,它将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。
在Android开发中,建造者模式通常用于创建复杂的对象,例如:AlertDialog等。
下面是建造者模式的示例代码:
public class AlertDialog { private String title; private String message; private boolean cancelable; private Listbuttons; private AlertDialog(String title, String message, boolean cancelable, List buttons) { this.title = title; this.message = message; this.cancelable = cancelable; this.buttons = buttons; } public String getTitle() { return title; } public String getMessage() { return message; } public boolean isCancelable() { return cancelable; } public List getButtons() { return buttons; } public static class Builder { private String title; private String message; private boolean cancelable; private List buttons = new ArrayList<>(); public Builder setTitle(String title) { this.title = title; return this; } public Builder setMessage(String message) { this.message = message; return this; } public Builder setCancelable(boolean cancelable) { this.cancelable = cancelable; return this; } public Builder addButton(AlertDialogButton button) { buttons.add(button); return this; } public AlertDialog build() { return new AlertDialog(title, message, cancelable, buttons); } } } public class AlertDialogButton { private String text; private View.OnClickListener listener; public AlertDialogButton(String text, View.OnClickListener listener) { this.text = text; this.listener = listener; } public String getText() { return text; } public View.OnClickListener getListener() { return listener; } } // Usage example AlertDialog alertDialog = new AlertDialog.Builder(context) .setTitle("Title") .setMessage("Message") .setCancelable(false) .addButton(new AlertDialogButton("OK", new View.OnClickListener() { @Override public void onClick(View v) { // Handle button click } })) .addButton(new AlertDialogButton("Cancel", new View.OnClickListener() { @Override public void onClick(View v) { // Handle button click } })) .build(); alertDialog.show();
在该示例代码中,AlertDialog类声明了一个Builder类,该类使用流畅接口风格的API来创建AlertDialog对象,并提供了setXXX()方法来设置各种属性。当所有属性都设置完成后,调用build()方法来创建AlertDialog对象,这个过程可以看作是具体构建者的实现。Builder类同时也声明了AlertDialogButton类来实现对按钮的封装。然后,通过调用AlertDialog.Builder类的静态方法,可以使用Builder类创建AlertDialog类的实例。
五、适配器模式
适配器模式是一种结构型模式,它允许不兼容接口之间进行合作。
在Android开发中,适配器模式通常用于显示列表数据,例如:ListView或RecyclerView中的数据适配器。
下面是适配器模式的示例代码:
public interface Item { int getItemType(); } public interface ItemViewBinder{ void onBindItemView(ItemViewHolder viewHolder, T item); } public class ItemViewHolder extends RecyclerView.ViewHolder { private SparseArray views = new SparseArray<>(); public ItemViewHolder(View itemView) { super(itemView); } public T getView(int viewId) { View view = views.get(viewId); if (view == null) { view = itemView.findViewById(viewId); views.put(viewId, view); } return (T) view; } } public class MultipleTypeAdapter extends RecyclerView.Adapter { private List - items = new ArrayList<>(); private SparseArray
> viewBinders = new SparseArray<>(); public void register(Class clazz, ItemViewBinder binder) { viewBinders.put(clazz.hashCode(), binder); } public void setItems(List - items) { this.items = items; notifyDataSetChanged(); } @Override public int getItemViewType(int position) { return items.get(position).getItemType(); } @NonNull @Override public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { ItemViewBinder binder = viewBinders.get(viewType); View itemView = LayoutInflater.from(parent.getContext()) .inflate(binder.getLayoutRes(), parent, false); return new ItemViewHolder(itemView); } @Override public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { Item item = items.get(position); ItemViewBinder binder = viewBinders.get(item.getItemType()); binder.onBindItemView(holder, item); } @Override public int getItemCount() { return items.size(); } } public class TextItem implements Item { private String text; public TextItem(String text) { this.text = text; } @Override public int getItemType() { return TextItem.class.hashCode(); } public String getText() { return text; } } public class TextViewBinder implements ItemViewBinder
{ @Override public void onBindItemView(ItemViewHolder viewHolder, TextItem item) { TextView textView = viewHolder.getView(R.id.text_view); textView.setText(item.getText()); } @LayoutRes @Override public int getLayoutRes() { return R.layout.item_text; } } // Usage example MultipleTypeAdapter adapter = new MultipleTypeAdapter(); adapter.register(TextItem.class, new TextViewBinder()); List - items = new ArrayList<>(); items.add(new TextItem("Hello, world!")); items.add(new TextItem("Hello, Android!")); adapter.setItems(items); recyclerView.setAdapter(adapter);
在该示例代码中,Item接口定义列表项,ItemViewBinder接口定义视图绑定器,负责将Item绑定到RecyclerView.ViewHolder中,而ItemViewHolder则表示ViewHolder对象。MultipleTypeAdapter使用SparseArray保存视图绑定器,这样只需要使用Item的类名的hashCode作为key,就可以方便地获取到它对应的视图绑定器。
没有注册的Item类型将会引发运行时异常,因此最好提供默认的视图绑定器。然而这个例子没有提供默认的视图绑定器,因为它只是用来演示适配器的工作原理。