Java中对单一职责思想的理解
在Java中最主要的思想是面向对象,而面向对象相对于以往面向过程的思维方式有着明显的优势,
因为面向对象可以做到明确的职责划分,让每个对象各司其职,这样不仅让代码结构更加的清晰,而且对后期的维护和修改有很大的帮助,下面我以一个简易的ATM系统来介绍一下使用单一职责带来的优势~
本次设计的ATM系统的主要结构如下:
- 账户类
- 窗口类(登录、菜单、查询、改密、存款、取款、转账)
- 接口
- 接口的实现方法
如下为实现步骤:
首先,我们创建一个用户类,其属性包括账户名,密码,以及余额,并赋予其相应的get,set方法
账户类主要用于实现账户对象的创建,使每一个用户拥有相同的属性和方法
public class CodeBean {
private String code;
private String pwd;
private int money;
public CodeBean(String code, String pwd, int money) {
super();
this.code = code;
this.pwd = pwd;
this.money = money;
}
public CodeBean() {
super();
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public int getMoney() {
return money;
接下来根据业务需求,我们创建一个接口,来定义我们的业务需求:
public interface ICodeService {
/**
* 登录方法
* @param code
* @param pwd
* @return登录是否成功
*/
public boolean login(String code,String pwd);
/**
* 查询
* @author Administrator
*得到登录帐号的余额
*/
public int getCodeMoney();
/**
* 存款
* @param sm 存款金额
*/
public void saveMoney(int sm);
完成了接口的创建之后,我们就需要对接口中的方法进行具体的实现**,需要注意的是:我们的接口实现类这里是独立于接口之外的,也就是说,当我们的实现方法需要作出相应的调整时候,只需要重新编写一个实现类,而不需要再改变其余的代码,这样,提高了代码的灵活性,也让代码的维护变得简单**
public class CodeServiceImpl implements ICodeService{
/**
* 帐号数组
*/
private static CodeBean[] codeArray = {
new CodeBean("001","111",5000),
new CodeBean("002","222",8000),
new CodeBean("003","333",4000)
};
/**
* 登录帐号
*/
private static CodeBean loginCode;
@Override
public boolean login(String code, String pwd) {
for(int i = 0 ;i<codeArray.length;i++) {
if(codeArray[i].getCode().equals(code)
&& codeArray[i].getPwd().equals(pwd)) {
loginCode = codeArray[i];
return true;
}
}
return false;
}
@Override
public int getCodeMoney() {
return loginCode.getMoney();
}
@Override
public void saveMoney(int sm) {
loginCode.setMoney(loginCode.getMoney() + sm);
}
@Override
public boolean sellMoney(int gm) {
if(gm > loginCode.getMoney()) {
return false;
}
loginCode.setMoney(loginCode.getMoney() - gm);
return true;
}
@Override
public String updatePwd(String oldPwd, String newPwd, String rePwd) {
String info = "";
if((oldPwd.equals(loginCode.getPwd()) == false)) {
info += "原密码错误\n";
}
if(newPwd.equals(rePwd) == false) {
info += "两次密码不一致\n";
}
if(info.length() != 0) {
return info;
}
loginCode.setPwd(newPwd);
return null;
}
@Override
public String transMoney(String tranCode, int money) {
String info ="";
CodeBean transCode = checkCode(tranCode);
if(checkCode(tranCode) == null) {
info += "转账账号不存在\n";
}
if(money > loginCode.getMoney()) {
info += "余额不足\n";
}
if(info.length() != 0) {
return info;
}
loginCode.setMoney(loginCode.getMoney() - money);
transCode.setMoney(transCode.getMoney() + money);
return null;
}
/**
* 验证帐号是否存在
* @param code 帐号
* @return 是否存在
*/
private CodeBean checkCode(String code) {
for(int i = 0;i<codeArray.length;i++) {
if(code.equals(codeArray[i].getCode())) {
return codeArray[i];
}
}
return null;
}
}
在完成对接口方法的实现之后,我们需要将这些方法定义在不同的GUI窗口中,这里我们将不同的窗口单独划分,并在相应的窗口中调用需要的实现类对象,来实现窗口功能的赋予,当我们重新创建一个接口的实现类来调整实现方法时,我们只需要更新窗口中调用的实现类对象就可以完成对方法的切换,这样使代码变得更加的灵活,具有很高的可调整性
**登录窗口**
public class LoginFrame extends JFrame{
private MyTxt loginTxt = new MyTxt("帐号:",100,100,this);
private MyTxt pwdTxt = new MyTxt("密码:",100,200,this);
public LoginFrame() {
this.setLayout(null);
init();
this.setTitle("登录窗口");
this.setVisible(true);
this.setSize(500, 500);
this.setDefaultCloseOperation(3);
this.setLocationRelativeTo(null);
}
private void init() {
MyButton loginButton = new MyButton("登录",100,300,this);
loginButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
login();
}
});
}
public void login() {
String code = loginTxt.getText();
String pwd = pwdTxt.getText();
if(new CodeServiceImpl().login(code, pwd) == true) {
this.dispose();
new MainFrame();
JOptionPane.showConfirmDialog(null, "登录成功");
}else {
JOptionPane.showConfirmDialog(null, "帐号密码错误");
}
}
public static void main(String[] args) {
new LoginFrame();
}
}
**取款窗口**
public class GetFrame extends JFrame{
public GetFrame(){
this.setLayout(null);
this.setTitle("取款窗口");
this.setSize(600,400);
this.setVisible(true);
this.setDefaultCloseOperation(3);
this.setLocationRelativeTo(null);
init();
}
private void init() {
MyTxt getTxt = new MyTxt("取款金额:",100,100,this);
MyButton sureButton = new MyButton("确定",100,150,this);
MyButton backButton= new MyButton("返回",230,150,this);
backButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
GetFrame.this.dispose();
new FindFrame();
}
});
sureButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(new CodeServiceImpl().sellMoney(Integer.parseInt(getTxt.getText())) == true) {
JOptionPane.showConfirmDialog(null, "取款成功");
GetFrame.this.dispose();
new FindFrame();
}else {
JOptionPane.showConfirmDialog(null, "余额不足");
}
}
});
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new GetFrame();
}
}
**转账窗口**
public class TransFrame extends JFrame {
public TransFrame(){
this.setLayout(null);
this.setTitle("取款窗口");
this.setSize(600,400);
this.setVisible(true);
this.setDefaultCloseOperation(3);
this.setLocationRelativeTo(null);
init();
}
private void init() {
MyTxt transCodeTxt = new MyTxt("转账帐号:",100,100,this);
MyTxt transMoneyTxt = new MyTxt("转账金额:",100,150,this);
MyButton sureButton = new MyButton("确定",100,230,this);
MyButton backButton= new MyButton("返回",300,230,this);
backButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
TransFrame.this.dispose();
new FindFrame();
}
});
sureButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String info = new CodeServiceImpl().transMoney(transCodeTxt.getText(),Integer.parseInt(transMoneyTxt.getText()) );
if(info == null) {
JOptionPane.showConfirmDialog(null, "转账成功");
TransFrame.this.dispose();
new FindFrame();
}else {
JOptionPane.showConfirmDialog(null, info);
}
}
});
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new TransFrame();
}
}
在窗口类中,我们只需要定义相应的按钮和按钮关联即可,其余方法都调用实现类即可
结束语:使用单一职责划分的思想,可以让代码更加有层次感和灵活性,每个类各司其职,当我们需要调整时,只需要对相应的类中的代码和它们的连接关系作出调整即可。
而如果将方法和窗口代码写在一起,容易让代码内容复杂,修改起来也比较容易出问题,使用单一职责思想,只需要点对点作出调整即可完成,且出错率较低,思维清晰。
当我们需要调整窗口,就对窗口类进行改变,而其中不会涉及到具体的实现,我们将具体的实现已经封装在实现类中。
单一职责划分可以让我们的代码结构和思路清晰,可调整性高,后期维护方便,是一种非常好的编程思路,希望大家看完本文章对Java编程有更多的理解和思考,以后我还会分享更多相关的编程技术和思考方式,欢迎大家一起交流和探讨~