软件系统的通用三层架构
表示层:位于系统的最外层(最上层),离用户最近。用于显示数据和接收用户输入的数据,只提供软件系统与用户交互的界面。
业务逻辑层:位于表示层和数据访问层之间,专门负责处理用户输入的信息,或者是将这些信息发送给数据访问层进行保存,或者是通过数据访问层从数据库读出这些数据。该层可以包括一些对”商业逻辑“描述的代码在里面。业务逻辑层是表示层和数据访问层之间的桥梁,负责数据处理和传递。
数据访问层:仅实现对数据的保存和读取操作。数据访问包括访问数据库系统、二进制文件、文本文档或是XML文档。数据访问层只负责对数据的访问存取工作。
三层架构各层的职责分配
表示层(UI):只接收用户输入的数据,并将业务逻辑层处理数据的结果显示给用户。
业务逻辑层(DLL):只负责对数据的业务处理,开发人员不要在业务逻辑层里写访问数据库的SQL语句。业务逻辑层可以验证用户输入的数据、缓存从数据库中读取的数据等等。
数据访问层(DAL):最好不要出现任何与业务逻辑和界面设计相关的代码。也就是说,要保证数据访问层中方法的功能仅负责存储或读取数据就可以了。
举一个例子
如我们一直在进行举例的自动售卖机的架构可变成一下模样
然而,由于每一层往往不是同一个人来写,但是层与层之间又会有必要的交互,如service层的编写时常常会运用到DAO层的方法,所以这时候将会用到接口。
接口
官方解释:Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。
个人理解:
接口的声明
接口的声明语法格式如下:
[可见度] interface 接口名称 [extends 其他的接口名] {
// 声明变量
// 抽象方法
}
如
```
/**
* @author Administrator
*业务层的借口
*定义了两个方法
*方法一是关于登陆的借口,登陆成功输出true,失败输入flase
*方法二是关于注册的借口,用户名已存在输出1,密码不一致输出2,注册成功输出3
*
*/
public interface UserManage { //功能不用直接写出来,只用写出方法的定义
public boolean login(String name,String password ); //不用写他的功能,所以不用写{}
public String regist(String name,String pwd1,String pwd2);
}
接口的使用
public class UserMenu {
public static void main(String[] args) {
UserManage userManage=null;//当接口的实现还没有写好的时候用该写法
// UserManage userManage=new UserManageImpl()l;//当接口的实现写好的时候用该写法
boolean login=userManage.login(username, pwd); //像普通方法一样直接调用
String regist=userManage.regist(name, pwd1, pwd2);
}
接口的实现
当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。
类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。
类名一般设置为接口名+impl
实现一个接口的语法,可以使用这个公式:
ublic class 类名 .implements 接口名称[, 其他接口名称, 其他接口名称…, …]
例如 在这里面的方法就要写具体功能出来了
public class UserManageImpl implements UserManage {
UserDao userDao=new UserDaoImapL(); //在dao层没写好前用null代替
@Override
//调用dao层查询是否在数据库存在——》如果不存在,传回null,如果存在传回一个用户对象
public boolean login(String name, String password) {
// TODO Auto-generated method stub
User user=userDao.findUserByName(name); //来自数据访问层
if(user==null){return false;}
else{
if(password.equals(user.getPassword())){return true;}
}
return false;
}
@Override
public String regist(String name, String pwd1, String pwd2) {
//调用dao层的功能检查用户名是否存在
boolean checkUserExsit= userDao.checkUserIfExsit(name);
if(checkUserExsit){
return "1";
}
else{
if(pwd1.equals(pwd2)){
User u=new User();
u.setPassword(pwd1);
u.setUsername(name);
userDao.addUser(u);
return "3";
}
else {
return "2";}}
}
}
关于登录注册系统的开发
模拟登录系统的登录和注册功能
1登录功能:输入账号和密码登录成功(即账号在数据库里面且密码正确)的话输出登录成功,登录失败显示登录失败
2注册功能;输入账号和两次密码。如果已经存在,则提醒他用户名已经存在,若密码不一致,则提醒密码不一致,若没出现这两个问题,便将账号密码存入数据库,且提醒注册成功
业务层的接口
/**
* @author Administrator
*业务层的借口
*定义了两个方法
*方法一是关于登陆的借口,登陆成功输出true,失败输入flase
*方法二是关于注册的借口,用户名已存在输出1,密码不一致输出2,注册成功输出3
*
*/
public interface UserManage {
public boolean login(String name,String password );
public String regist(String name,String pwd1,String pwd2);
}
界面层
import java.util.Scanner;
import javax.imageio.spi.RegisterableService;
public class UserMenu {
public static void main(String[] args) {
UserManage userManage=new UserManageImpl();
boolean target=true;
while(target){
Scanner sc=new Scanner(System.in);
System.out.println("1,登陆 2,注册3退出");
String nextline=sc.nextLine();
switch (nextline) {
case "3":target=false;
break;
case "1":System.out.println("请输入账号");
String username=sc.nextLine();
System.out.println("请输入密码");
String pwd=sc.nextLine();
boolean login=userManage.login(username, pwd);
if(login){ System.out.println("恭喜你登陆成功");}
else{ System.out.println("密码或账号输入异常");}
break;
case "2":
System.out.println("请输入账号");
String name=sc.nextLine();
System.out.println("请输入密码");
String pwd1=sc.nextLine();
System.out.println("请再次输入密码");
String pwd2=sc.nextLine();
String regist=userManage.regist(name, pwd1, pwd2);
switch (regist) {
case "1":
System.out.println("账号已存在");
break;
case "2":
System.out.println("两次输入密码不一致");
break;
case "3":
System.out.println("恭喜你注册成功");
break;
}break;
}
}
}
}
业务层的接口的实现
public class UserManageImpl implements UserManage {
UserDao userDao=new UserDaoImapL(); //在dao层没写好前用null代替
@Override
//调用dao层查询是否在数据库存在——》如果不存在,传回null,如果存在传回一个用户对象
public boolean login(String name, String password) {
// TODO Auto-generated method stub
User user=userDao.findUserByName(name); //来自数据访问层
if(user==null){return false;}
else{
if(password.equals(user.getPassword())){return true;}
}
return false;
}
dao层的接口
/**
* @author 冷酷无情杀手
* 是dao层的借口
* 方法findUserByName是根据用户名寻找数据库中是否存在该用户,有着输入用户,没有输入null
* 方法checkUserIfExsit检查该用户名是否在数据库中已经存在,如果是返回true,否则输出false
* 方法addUser是将成功注册的用户的账号密码输入数据库中
*/
public interface UserDao {
public User findUserByName(String name);
public boolean checkUserIfExsit(String name);
public void addUser(User user);
}
dao层接口的实现
public class UserDaoImapL implements UserDao{
@Override
public User findUserByName(String name) {
User findUser=UserDataBase.userMap.get(name);
return findUser;
}
@Override
public boolean checkUserIfExsit(String name) {
boolean containUser=UserDataBase.userMap.containsKey(name);
return containUser;
}
@Override
public void addUser(User user) {
UserDataBase.userMap.put(user.getUsername(),user);
}
模拟数据库
import java.util.HashMap;
public class UserDataBase {
public static HashMap<String,User> userMap=new HashMap<>(); //一开始先将其创建好,static静态不用声明类,HashMap的key装账号,value装类User
}
User类
public class User {
private String username;
private String password;
public User(){};
public User(String username, String password) {
super();
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password
+ ", getUsername()=" + getUsername() + ", getPassword()="
+ getPassword() + ", getClass()=" + getClass()
+ ", hashCode()=" + hashCode() + ", toString()="
+ super.toString() + "]";
}
}