工作中会带一些实习生或新人,大多缺乏经验,项目调试是他们很头疼的问题,代码出了问题往往就束手无策了,很影响工作效率。其实代码调试是有步骤可循的,代码出了问题要做的第一件事情是定位问题,只有知道问题出在哪才能解决。
一个Java Web项目通常是由前端和后端组成的,请求是由前端发送给后台代码处理的,所以我们要做的第一件事情就是确定问题出在前端还是后端,先要保证前端发送给后端的请求参数是对的,有些同学在请求参数不对或者请求根本没有到达后台的情况下盲目地去检查后台代码是不对的。
前台请求通常通过form、超链接或ajax等方法提交给后台,我们必须确定提交的链接是对的,然后是参数,提交的参数我们可以通过浏览器地址或者一些浏览器调试工具(例如火狐的firebug)得到。
如果请求链接是对的、参数也是对的,那就是后台的问题了,后台问题通常通过eclipse的debug工作调试,但有一种情况,就是开发中会运用一些mvc框架,例如struts2、spring
mvc等,我们在后台某个地方加断点根本就没反应,这时候有个很简单的方法,把断点加到control层的代码入口处,如果还没反应,那就是框架配置问题了,要检查配置对不对。
对象,你可以理解成一种具有属性和行为的实体,它可向外部提供服务。而使用这个对象,可忽略其内部的细节,只需要知道使用这种服务时的“投入”、“产出”即可,因此,“高内聚、低耦合”是面向对象编程的基本思想。
略举一例,平时我们工作中要删除某条数据,一般不是真的delete掉,而是用一个status标识,status为-1表示删除,你写删除接口时完全可以这么写:
Class UserService{
private UserDao userDao;
public void deleteUser(User user){
user.setStatus(-1);
userDao.update(user);
}
}
这个逻辑其实执行的是更新操作,但接口名仍是deleteUser,因为它提供的确实是删除“服务”,调用接口时我只需要知道我调用这个接口时会删除对象,至于它怎么实现,我管不着。
Java中到处是指针引用,习惯了使用c语言指针的程序员往往会乱用指针,而破坏了面向对象的思想,比如,我要查询某个用户的密码,有人可能会这么写:
Class UserService{
private UserDao userDao;
public void queryUserPasswd(int id,User user){
String passwd=userdao.getUserPasswd(id)
User.setPasswd(passwd);
}
}
这种写法在语法上没什么问题,也能得到正确的值,但传个user对象进来就有些不妥了,我要得到密码,传个用户的密码,只要给个id就可以把密码返回给调用者了,干嘛要让人再传个对象进来?
作为一个项目经理,在工作过程中,确实会遇到令人哭笑不得的接口,就像上面那个删除接口吧,有人会这么写:
Class UserService{
public void deleteUser(UserDao userDao ,User user){
user.setStatus(-1);
userDao.update(user);
}
}
这接口写得,让人摸不着头脑了,我删除一个user对象,还要传个userDao给你,意思是你为我提供服务,我还要给个工具给你,这说不通吧!
Java是纯粹的面向对象语言,写Java程序时要时刻记住,你在为别人提供服务,为别人提供服务就不应该提出过多的附加要求。这个问题在使用MVC模式分层思想的时候体现得更加严重。在使用MVC模式开发的时候,往往将整个项目分成几层:action层、service层、数据库处理层(dao层)等等,每一层往往由不同的程序员编写,这时候要格外提醒自己在为别人提供服务。在一个新项目开始的时候往往会出现一个问题:在增加某条数据时,要对这条数据的字段进行验证,不能为空或者长度过长等等,如果没有验证容易抛错,在分层编写接口时,开发人员经常想这个验证应该在上层或者下层做吧,我这边得到的数据是正确的,最后导致谁都没做验证。只要你记住了提供“服务”的思想,就不应该要求别人给你的数据是正确的,而是应该处理各种非正常问题,保证用户给你的任何数据你都能给出相应的返回,当然,在实际的项目中项目经理可能规定数据验证在service层做。
Android Adapter 是将数据绑定到UI 界面上的桥接类。 Adapter负责创建和显示每个项目的子View和提供对下层数据的访问。支持Adapter绑定的UI控件必须扩展Adapter View抽象类。创建自己的继承自AdapterView的控件和创建新的Adapter类来绑定它们是可能的。
Android 系统本身提供了两种现成的Adapter 供我们使用。
1.ArrayAdapter:它是一个绑定View到一组对象的通用类。默认情况下,ArrayAdapter绑定每个对象的toString值到layout中预先定义的TextView空间上。构造函数允许用户使用更加复杂的Layout或者通过重写getView方法来扩展类从而使用TextView的替代物
2.SimpleCursorAdapter:它绑定View到Content Provider 查询返回的游标上。指定一个XML layout定义,然后将数据集的每一列的值绑定到layout中的一个View
写自己的Adapter类实现更多复杂的UI界面和数据绑定
public class MyAdapter extends SimpleAdapter {
private LayoutInflater mInflater;
private Context context;
private List<Map<String,Object>> list;
private int resource;
private String[] tags;
private int[] ids;
public MyAdapter(Context context, List<Map<String,Object>> items, int resource,
String[] tags,int[] ids) {
super(context, items, resource, tags, ids);
this.mInflater = LayoutInflater.from(context);
this.context = context;
this.list = items;
this.resource = resource;
this.tags = tags;
this.ids = ids;
}
public int getCount() {
return list.size();
}
public Object getItem(int position) {
return list.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
convertView = super.getView(position, convertView, parent);
if (convertView == null) {
Toast.makeText(context, "this is null", 2000).show();
} else {
}
ImageView more = (ImageView) convertView.findViewById(R.id.iv_more);
more.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
Intent intent = new Intent(context, VehicleInfoActivity.class);
intent.putExtra("vehicleID", VehicleListActivity.idList.get(position));
intent.putExtra("CameraID", "0");
Toast.makeText(context, "sssssss", 2000).show();
context.startActivity(intent);
}
});
return convertView;
}
}
主要重载getCount 方法,getView方法 getItem方法 getItemId方法; 参数解析:context:传入的上下文Activity, items 绑定数据的列表, resource layout布局ID, tags 绑定数据的key, ids Item 中对应key的资源ID。 在getView中自定义Item里面的事件监听,自定义新的重载后的显示界面返回 convertView。 如果需要使用到父类SimpleAdapter 显示效果需要调用super.getView方法为 convertView 赋值。