自己理解的设计模式遵循的原则:
1)功能单一明确,设计一个类的意图要明确,不能大包大揽什么功能都继承进去
2)对于扩展要开放,修改要关闭。软件通常都有需求变化,变化过程中通过扩展的方式来实现需求变化,而不是通过修改原有的方法,因为修改原有的方法会导致原来方法的调用方会出问题,这样层层调用出问题。
3)变化的进行抽象,不变的进行具体。设计代码过程中会面对很对可变的东西,比如在实现一个功能的时候,能够运用不同的方式进行实现,这个时候可以将每个具体的实现方法进行抽象,真正不变的是这个方法要实现的目的
单例模式:
单例模式太多了,在整个应用中只有一个,标准的单例模式写法:
public class singleton{ private volatitle static instance; //使用volatile 表明每次都会去内存中读取最新的值; static 表明生成周期和当前应用一样 public singleton(){ } public static singleton getInstance(){ //同样使用静态方法获取 if(instance == null){ synchronized (singleton.classs){ //在多线程中获取需要进行同步,或者会导致同步问题 if(instance == null) instance = new singleton(); } } return instance; } }
Builder模式
当需要创建一个对象需要很多变量组合而成,这个时候可以考虑将这个对象的创建过程和对象的表示分离开来,这样可以很简洁的构建一个复杂的对象。
常见的builder模式有创建dialog的过程。
AlertDialog.Builer builder=new AlertDialog.Builder(context); builder.setIcon(R.drawable.icon) .setTitle("title") .setMessage("message") .setPositiveButton("Button1", new DialogInterface.OnclickListener(){ public void onClick(DialogInterface dialog,int whichButton){ setTitle("click"); } }) .create() .show();
在这种情况下当创建一个dialog时,并不需要分别去为某一个对象单独写一个构造函数,而且创建过程一目了然。
策略方法模式
定义:有一系列的算法,将每个算法封装起来(每个算法可以封装到不同的类中),各个算法之间可以替换,策略模式让算法独立于使用它的客户而独立变化。
比如在注册一个用户信息时,可能最终会注册到不同的服务器上,但是对于上层代码并不关心最终用户数据到哪,只需要有地方存储就可以,所以可以抽象出存储函数,真正的实现让其实现的子类去做。
抽象出注册用户信息函数:
public interface IUserManager { /** * @Decription 注册 **/ void register(final UserDALEx user, final ICallBackObject<UserDALEx> callBack); /** * @Decription 登陆 **/ void login(final Context context, final String name, final String psw, final ICallBackObject<UserDALEx> callBack); /** * @Decription 根据输入查询用户 **/ void queryUsers(String username,int limit,final ICallBackObject<List<UserDALEx>> callBack); ... }
定义不同的实现方法
public class BmobUserManager implements IUserManager { @Override public void register(UserDALEx user, final ICallBackObject<UserDALEx> callBack) { 。。。 } @Override public void login(Context context, String name, final String psw, final ICallBackObject<UserDALEx> callBack) { ... } @Override public void queryUsers(String username, int limit, final ICallBackObject<List<UserDALEx>> callBack) { .... }
当然这里还肯定可以用其他对象的方法去实现它。在应用的初始化中过程中设置使用哪一种方法.
//初始化云数据库 IUserManager userManager = new BmobUserManager(); Bmob.initialize(this, NCAppContext.ApplicationID); CloudManager.getInstance().setUserManager(userManager); 。。。 }
工厂方法模式
我们创建的activity或者fragment中,定义基类的时候,可以将每个界面不同的地方抽象出来,让真正实现的子类去实现该统一的方法。
基类的方法
public interface IBase<P> { /** * 功能描述:给view绑定数据 **/ void onInitView(Bundle savedInstanceState); /** * 功能描述:获得布局文件Id **/ int getLayoutResource(); }
在不同的实现子类activity或者fragment中去实现该方法
public class LoginActivity implements IBaseview{ @Override public void onInitView(Bundle savedInstanceState) { //.... } @Override public int getLayoutResource() { return R.layout.activity_login; } }
观察者模式
在安卓中观察者模式用的比较多的地方在数据库变化或者listview内容有变化时,使用notifyDataSetChanged()方法。
public ContactListAdapter netAdapter; mNetDataList.addAll(mList); netAdapter.notifyDataSetChanged();
notifyDataSetChanged()该函数的定义在adapter中
public final void notifyDataSetChanged() { mObservable.notifyChanged(); }
通知所有被观察者去更新。
组合模式
这种模式在安卓中最常见,Android中的view是一种树形结构,每个viewGroup包含一些列的view,而每个viewGroup本身又可以当做一个view,所以最终手机上呈现出来的界面,是由一个个view组合而成的。
适配模式
其实适配器模式很容易理解,我们在Android开发时也经常用到。比较典型的有ListView和RecyclerView。为什么ListView需要使用适配器呢?主要是,ListView只关心它的每个ItemView,而不关心这个ItemView具体显示的是什么。而我们的数据源存放的是要显示的内容,它保存了每一个ItemView要显示的内容。ListView和数据源之间没有任何关系,这时候,需要通过适配器,适配器提供getView方法给ListView使用,每次ListView只需提供位置信息给getView函数,然后getView函数根据位置信息向数据源获取对应的数据,根据数据返回不同的View。
模板方法模式
定义:定义一个操作中的算法框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定的步骤。
这种模式也相当常见,比如我们的activity或者fragment,在base中定义了一些列的周期函数,基本把整个activity的框架全部定义好了,所以我们只需要进程基类的activity或者fragment方法,然后在定义好的周期函数中实现我们需要的内容就可以,而不用关心整个activity的启动所有过程。
代理模式
定义:为其他类提供一种代理以控制这个对象的访问。
在安卓中进程通信是一个很常见的东西,如果需要进行进程通信则可以通过使用AIDL来获取远程service的代理,然后我们可以通过这个代理来执行响应的操作。
private ServiceConnection mServiceConnection = new ServiceConnection(){ @Override public void onServiceConnected(ComponentName name, IBinder service){ mTransation = ITransactionManager.Stub.asInterface(service); .... } }
上面介绍的都是app代码中很常见,并且我们在设计代码是经常会用到的,当然在还有其他很多设计模式没有介绍,这里就不一一介绍了。