数据访问对象模式/DAO
本次仅实现读写部分用户数据,在每次游戏结束时记录本次游戏相关数据并输出排行榜,且数据存储在**本地文档**中,输出在控制台,无图形及与用户交互界面。
示例
UML类图
代码
UserDaoImpl(Impl后缀意为接口实现类)
public class UserDaoImpl implements UserDao{
private List<User> users;
public User temp;
//游戏难度
public String degree;
public void setDegree(String degree){
this.degree=degree;
}
/**
* 读取数据
*/
public void readFile(){
users = new LinkedList<User>();
BufferedReader reader;
try {
FileInputStream fileInputStream = new FileInputStream("RankList/"+degree+"RankList.txt");
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,StandardCharsets.UTF_8);
reader = new BufferedReader(inputStreamReader);
String tempString = null;
// 一次读入一行,直到读入null为文件结束
while ((tempString = reader.readLine()) != null) {
String tempStringSpace[] = tempString.split("\\$");
User user = new User(tempStringSpace[0],Integer.parseInt(tempStringSpace[1]),tempStringSpace[2],tempStringSpace[3]);
users.add(user);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public List<User> getAllUsers(){
return this.users;
}
public void doAdd(User user) {
for (User user1 : users) {
//同一用户名
if (user1.getUserName().equals(user.getUserName()) && user1.getDegree().equals(user.getDegree())) {
//更新最高分
if(user1.getScore() < user.getScore()){
//去除原分数
users.remove(user1);
}
//如果低于最高分则不更新
else{
return;
}
break;
}
}
//若列表中无任何游戏记录则直接添加
if(users.size()==0){
users.add(user);
}
else {
for (int i = 0; i < users.size(); i++) {
User user1 = users.get(i);
//插入在第一个比当前分数低的游戏记录前面
if (user1.getScore() < user.getScore()) {
users.add(i, user);
break;
}
//如果比所有游戏记录都低分则在最后面添加
if(i+1==users.size()){
users.add(user);
break;
}
}
}
writeFile(this.users);
}
public void doDelete(String userName){
for(User user : users){
if(user.getUserName() == userName){
users.remove(user);
System.out.println("Delete User: Name (" + userName +")");
//重新写入更新
writeFile(this.users);
return;
}
}
}
/**
* 写入文件
* @param users
*/
public void writeFile(List<User> users){
// 写文件的地方
File file = new File("RankList/"+degree+"RankList.txt");
// 文件字节流写入的类
FileOutputStream fos = null;
try {
// 使用字节流向目的地址写入文件
// 如果加第二个参数true,表示每次在原来的文件上追加东西
fos = new FileOutputStream(file, false);
for(User user : users){
String temp = user.getUserName()+"$"+Integer.toString(user.getScore())+"$"+user.getTime()+"$"+user.getDegree()+"\n";
fos.write(temp.getBytes(StandardCharsets.UTF_8));
}
//一般要把存入的数据刷新缓冲进去
fos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
User(要保存的数据集合)
随意添加任何想保存的数据(作为该对象的成员)
public class User {
private String userName;
private int score;
private String degree;
private String time;
public User(String userName,int score,String time,String degree)
{
this.userName = userName;
this.score = score;
this.degree = degree;
this.time = time;
}
public String getUserName(){
return this.userName;
}
public void setUserName(String userName){
this.userName=userName;
}
public int getScore(){
return this.score;
}
public void setScore(int score){
this.score = score;
}
public String getDegree(){
return this.degree;
}
public void setDegree(String degree){
this.degree = degree;
}
public String getTime(){
return this.time;
}
public void setTime(String time){
this.time = time;
}
}
输出(在控制台)
/**
* 读写游戏排行榜
*/
private void dealRankList(){
UserDaoImpl userDao = new UserDaoImpl();
SimpleDateFormat df = new SimpleDateFormat("MM-dd HH:mm");
String systemTime =df.format(new Date());
String username = "player";
userDao.doAdd(new User(username,this.score,systemTime,this.degree));
List<User> users = userDao.getAllUsers();
System.out.println("**************************************************************");
System.out.println(" 得分排行榜 ");
System.out.println("**************************************************************");
System.out.println(" 排 名 名称 分数 达成时间 难度 ");
int index = 1;
for(User user : users){
System.out.printf(" 第 %d 名 :%11s,%8d,%15s,%11s\n",index,user.getUserName(),user.getScore(),user.getTime(),user.getDegree());
index++;
}
}
一些tips
'''
1、String.split()
String有个方法是分割字符串 .split()。但是有写字符串是需要转义才能分割,不然就会出错。
需要转义的字符串:. $ | ( ) [ { ^ ? * + \\ 共12个特殊字符,遇到以这些字符进行分割字符串的时候,需要在这些特殊字符前加双反斜杠 \\
例如:
str.split("\\.")
str.split("\\$")
str.split("\\|")
str.split("\\(")
str.split("\\)")
str.split("\\[")
str.split("\\{")
str.split("\\^")
str.split("\\?")
str.split("\\*")
str.split("\\+")
str.split("\\\\")
'''
'''
[Ljava.lang.String;@4554617c
“[” 表示一维数组
"[["表示二维数组
"L"表示一个对象
"java.lang.String"表示对象的类型
"@"后面表示该对象的HashCode
'''
'''
一、注释该行
快捷键:Ctrl + /
使用Ctrl+ /, 添加行注释,再次使用,去掉行注释
二、注释该代码块
快捷键:Ctrl +Shift+ /
使用 Ctrl+Shift+ /, 添加块注释,再次使用,去掉块注释;
注意:如果已经写好代码块,使用块注释需要先选中要注释的块;
去除注释的时候,不需要全部选中这块代码,只用光标在注释内容上按Ctrl+Shift+/即可。
三、注释或说明该方法
快捷键
输入/** ,点击“Enter”,自动根据参数和返回值生成注释模板
'''
总结
数据访问对象模式(Data Access Object Pattern)或 DAO 模式用于把低级的数据访问 API 或操作从高级的业务服务中分离出来。以下是数据访问对象模式的参与者。数据访问对象接口(Data Access Object Interface) - 该接口定义了在一个模型对象上要执行的标准操作。数据访问对象实体类(Data Access Object concrete class) - 该类实现了上述的接口。该类负责从数据源获取数据,数据源可以是数据库,也可以是 xml,或者是其他的存储机制。模型对象/数值对象(Model Object/Value Object) - 该对象是简单的 POJO,包含了 get/set 方法来存储通过使用 DAO 类检索到的数据。