培训笔记之java 六

1.首先,先公布一下上次的程序的改进版本:
UserOp 类:

package com.superclass;

public interface UserOp {
 public int execute(Request request,Response reponse);
}

Request 类:
package com.superclass;

import java.util.HashMap;

public class Request {
 private HashMap requestData=new HashMap();
 
 public void setProperties(String name,Object value){
  requestData.put(name, value);
 }
 public Object getProperties(String name){
  return requestData.get(name);
 }
}

Response 类:
package com.superclass;

import java.util.HashMap;

public class Response {
 
private HashMap responseData=new HashMap();
 
 public void setProperties(String name,Object value){
  responseData.put(name, value);
 }
 public Object getProperties(String name){
  return responseData.get(name);
 }
}

QueryUser 类(查询的)
package com.op;

import com.data.User;
import com.superclass.Request;
import com.superclass.Response;
import com.superclass.UserOp;

public class QueryUser implements UserOp {

 /* (非 Javadoc)
  * @see com.superclass.UserOp#execute(com.superclass.Request, com.superclass.Response)
  */
 public int execute(Request request, Response reponse) {
  // TODO 自动生成方法存根
  String userId=(String)request.getProperties("userId");
  System.out.println("您所查询的用户Id为:"+userId);
  User user=new User();
  user.setUserId(userId);
  user.setUserName("xxxx");
  user.setPassWord("yyy");
  reponse.setProperties("User", user);
  return 0;
 }

}
AddUser 类
package com.op;

import com.data.User;
import com.superclass.Request;
import com.superclass.Response;
import com.superclass.UserOp;

public class AddUser implements UserOp {

 public int execute(Request request,Response reponse) {
  int succ = 0; 
  User user=(User)request.getProperties("User");
  System.out.println("添加用户的信息是:/n"+user+"/n添加成功");
  succ = 1;
  return succ;  
 }

}

UserFactory 类:

package com.factory;

import java.util.ResourceBundle;

import com.superclass.Request;
import com.superclass.Response;
import com.superclass.UserOp;

public class UserFactory {

 public static UserOp getUserOp(String command) {
  
  UserOp userOp=null;
  
  ResourceBundle resource = ResourceBundle.getBundle("command");
  String className=resource.getString(command);
  
  try {
    userOp=(UserOp)Class.forName(className).newInstance();   
  } catch (InstantiationException e) {
   // TODO 自动生成 catch 块
   e.printStackTrace();
  } catch (IllegalAccessException e) {
   // TODO 自动生成 catch 块
   e.printStackTrace();
  } catch (ClassNotFoundException e) {
   // TODO 自动生成 catch 块
   e.printStackTrace();
  }
  return userOp;
 }

}

Controller 类:

package com.control;

import javax.swing.JOptionPane;

import com.data.User;
import com.factory.*;
import com.superclass.Request;
import com.superclass.Response;

public class Controller {

 /**
  * @param args
  */
 public static void perform(Request request,Response response) {
  // TODO 自动生成方法存根
  String command=(String)request.getProperties("command");  
  UserFactory.getUserOp(command).execute(request, response);
 } 
}

调用方法:
package com.run;

import com.control.Controller;
import com.data.User;
import com.superclass.Request;
import com.superclass.Response;

public class DoAdd {
 
 public static void main(String[] args) {
  
  User user=new User();
  user.setUserId("0000");
  user.setUserName("mc");
  user.setPassWord("mm");
  Request request=new Request();
  request.setProperties("userId", "1");
  request.setProperties("command", "q");
  Response response=new Response();
  Controller.perform(request, response);
  user=(User)response.getProperties("User");
  System.out.println("您查询的用户信心是:"+user);
 }

}

资源文件:command.properties
a = com.op.AddUser
d = com.op.DeleteUser
u = com.op.UpdateUser
l = com.op.UserLogin
q = com.op.QueryUser

通过上面的程序,我们真正实现了关于数据库的所有操作的封装,那么以后我们是添加什么功能,在上述代码的情况下,我们不用改动任何类,只需添加新类,和改配置文件就行了。
在这个例子中,应用了如下原则:
 单一职责原则(高内聚)SRP(除了Controller类,它是作为控制类来用的)。
 开闭原则 OCP 一个Controller类,一个UserFactory类,把原来的if语句改成配置文件了,并且使用Class.forName消除了与子类的关系,动态生成类.
 里氏代换原则 LSP: 只要父类可以实现的用子类即可替换。反之不可。:主要是在Controller中,用父类实现的方法用子类能够替换(execute方法),但是在UserFactory中,用到的父类的地方用子类却不能替换。
 依赖倒转原则 DIP(谑称“好莱坞原则”) 从Controller中可以看出,在原来中都是直接依赖关系,但本程序中这中依赖关系在编译时体现不出来,可以实现动态的改变类之间的关系。
 接口隔离原则ISP: 这里没有多个接口,但是我们在接口里只写了一个方法,当然也可以写三个方法,但是这样的话会强迫客户接受不需要的方法。所以要么拆分接口,要么合并方法。
 组合/聚合复用原则CARP:本例中没有直接体现。
 迪米特法则LoD:在这里的Controller原来时与很多类建立了关系,但现在只和一个工厂类建立了关系,减少了与外界的接触。

由与在我的java培训笔记五里已经对该程序和OO设计原则有了详细的介绍,在这里就不多写了,有兴趣的同学可以查看我上一篇文章。

2.异常:
为什么要有异常:内部:设计时会产生缺陷,生产时也会产生缺陷,外部:用户使用时操作错误,还有不可控制的环境问题!以及一些不可预料的错误。
要控制问题:第一必须准确的定位问题所在,并能有效反馈;其次改进必须能持续,并能有效改正,只有这样才能形成良性循环。
异常则负责第一条任务。确定问题的所在。可以使用重构和测试来不断修正问题。

Basics of The UNIX Philosophy
Repair what you can — but when you must fail, fail noisily and as soon as possible.
UNIX哲学的基本原则

修复你能修好的—但是如果你必须失败,那就尽可能吵闹并快速的失败。

3.异常语法:

<1>.throw new Exception(); //main()方法不用再抛出异常了。
<2>.throws Exctption;
<3>.try{}catch(Execption e){};
4.异常的类继承结构:

                             |-OutOfMemory Error 
        |-InterNal Error  
    ______ Error      |-Unkonwn Error 
Throwable |                         |-NullPointer Exception   
     ______ Exception  |-Runtime Exception  |-.....   
        |-IO Exception
        |-....... 
异常的分类
Checked
需要使用try……catch语句包围或throws语句抛出的异常
及在编写代码是就确定异常处理策略,从而利用了编译时刻的检查机制,增强方法的契约。
Unchecked
不需要使用try……catch语句包围或throws语句抛出的异常

只有Runtime Exception不需要检查。

典型的运行时异常错误:如数组运行时越界!(不用Try,Catch包围。且一般运行时错误有可能是逻辑错误)

IllegalArgumentExcetpin("非法的参数异常");
5.自己编写异常类:

public class UserNameException extends RuntimeException{
 public UserNameException(String msg){
  super(msg);
 }
}
一般用在系统设计时定义异常。
可以通过:throw new UserNameException("asdfasf");来实现。
6.多线程简介
<1>.线程本身自己不能申请时间片。是由系统随机分配的。
<2>.在对全局变量,数据库,文件访问时都会出现资源共享的问题。(可以折衷解决,将大资源分配成小资源dengdeng)
例如上面的Response 类,可以这么写 加上互斥锁:
package com.superclass;

import java.util.HashMap;

public class Response {
 
private HashMap responseData=new HashMap();
 
 public synchronized void setProperties(String name,Object value){
  responseData.put(name, value);
 }
 public synchronized Object getProperties(String name){
  return responseData.get(name);
 }
}

另外在涉及到多线程时多用局部变量。

5.类集框架:Collections Frameword
由三部分组成:
 接口:包括Collection,List,Set,SortedSet,Map,SortedMap,Iterator
 实现:集合框架中接口的具体实现类:HashSet,HashMap........
List有先后概念,Set没先后概念.List已经排好序了,Set没有排序。SortedSet是排好序的Set。
Map是映射,是有Key和Value关系的。
Iterator是遍历集合的迭代器。相当于游标。
Collection接口时一组允许重复的对象,Set接口继承Collection,但不允许重复,List 允许重复,且下标有先后顺序。
HashSet未排序,TreeSet排序。(都不允许重复).
ArratList 适用与随即访问,且不必在除尾部的任何位置插入或删去元素。
LinkedList 适用与要频繁的从列表的中间位置等进行插入和删除操作。
Map接口不是Collection接口的继承。而是从自己的用于维护键-值关联的接口层次结构入手。按定义,该接口描述了从不重复的键到值的映射。经常做为数据库映射的工作。Map的entrySet()方法返回一个实现Map.Entry接口的对象集合。集合中每个对象都是底层的Map中的一个特定的键-值对。通过这个集合迭代,您可以获得每一条目的键值或对应修改。在Map中插入、删除、定位元素,HashMap试最好的选择,如果排序(按"键"的顺序排列),可以用TreeMap。
HashMap map=new HashMap();
String keyset=map.keySet();
Iteratro it=keyset.iterator();
map.put("111","111");
while(it.hasNext()){
 String key=it.next();
 String value=map.get(key);
 System.out.println(key+":"+value);
}
static变量会放在方法区,一般static程序块用来初始化类,或常量。
组合与聚合区别:
聚合的生命周期与引用类无关,组合与引用类有关。比如在一个类中引用单太类,那么单太类不随这个类的消失而消失。
组合是只生命周期与这个类有关,是在这个类中创建的,这个类消失了,那个就也消失了。

6.泛型
可以在类,变量,方法上加上<T>做为泛型,在类实例化时进行批量替换
比如:
package com.superclass;

import java.util.HashMap;

public class Request<E> {
 private HashMap requestData=new HashMap();
 
 public void setProperties(String name,Object value){
  requestData.put(name, value);
 }
 public E getProperties(String name){
  return (E) requestData.get(name);
 }
 public E getCommand(){
  return (E) requestData.get("command");
 }
}
其实泛型对基础数据类型比较好用,但是对处理逻辑时传递对象时不是特好用。

重点总结:基本数据类型,会有程序猜结果。字符串比较会考,会if-else switch case的转换。区分全局变量,类变量,成员变量,局部变量。数组字符串操作,判断输入的邮箱是否合法。类的装载的顺序。new 一个String 产生了几个对象,封装,单例,限定符范围。多态是重中之重,OO原则的概念。异常,还有用户的程序。让你设计一个结构实现开闭原则。或者让你写一个封装类,把数据很好的封装。


 到这里java的培训就暂时结束了,在这里感谢培训老师张老师。谢谢他的讲座。让我受益颇多,因为这次讲座主要是以练习为主,所以课间基本没有,上面的那些代码都是访张老师写的,在这里声明一下。在下一周里将是数据库和web培训,到时我也会将笔记发上来的,大家一起学习,一起进步。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值