//记录学习心得 后面有一个简单实现的小程序
前面有两篇博客,分别是这里,和这里//还在审核,超链接没贴.提到了JAVA设计模式中的单例模式和工厂模式
这里要说的是MVC框架.来看看MVC框架的定义:
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范
继续看更详细的解释:
用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。
这怎么很像一种设计的模式阿?这或许是广义上/笼统可以说是设计的一种模式吧, 但不是"设计模式"
单例/`工厂,是设计模式.
有书<<设计模式>>里对框架定义为一组相互协作的类,对于特定的一类软件,框架构成了一种可重用的设计. (又略不同于设计重用)
设计模式研究是一个设计问题的解决办法,一种设计的重用,一个模式可以用不同的框架/语言去实现.
框架是一个应用的体系结构;而设计模式是给出某一设计问题的解法.
框架是设计+代码的混合体
设计模式与语言无关,是一种知识体.//翻了资料,认识比较浅,姑且用这些比较皮毛的只言片语来区分两者
搜索MVC,肯定会有这样几张图,比较经典的是从这个博客里看到的这个:
尤其第二张图,文字都很直白.
总而言之,这个模式就是 泾渭分明 地将程序的"输入" "处理" " 输出"给分开,分开的目的是什么?
在我看来,目的主要也是两个字: "解耦".
解耦的目的大同小异:
0.比如:清晰的分层有利于各个层次的集中注意力以突破.
1. 有利于管理复杂的程序
2. 对于某一部分的修改能尽可能少地修改其他部分从而加强了扩展性和调试性 等等...
要实现各个部件,比如这里的 MODEL VIEW CONTROLLER 的分离, 一般是三种构思的组合..
Servlet 交互式地浏览 修改数据
JavaBean提供符合一致性设计模式的公共方法将内部域暴露成员属性 (比如GET SET 体现的思想)
JSP ...鹅表示母鸡阿,说是一种动态网页技术标准
按上面的第一张循环图来看. 他把起点设置在了 即将与 Controller 互动的 用户里.
Controller负责等待用户输入 -> 数据丢给Model -> Model 进行业务逻辑判断+数据库存取 最后导致-> View Update
这里我们扣一下三个部分的相关说明:
Model(模型)表示应用程序核心(比如数据库记录列表)。
View(视图)显示数据(数据库记录)。
Controller(控制器)处理输入(写入数据库记录)。
我写下面这个小程序的时候,就遇到这样一个问题:
如果这三个程序,完全构成了一个圈,那真的能形成吗?
Controller 得到数据,提交给 Model (势必关系到Model)
Model处理一下数据的业务逻辑,存取一下数据,通知一下视图更新(势必关系到View)
View进行下一步读取数据,数据给到Controller
这样的依赖关系可以通过 接口回调 实现
--->那么比如View是一个交互的窗口界面,负责监听窗口得到数据,传递数据和一个事件检查器给Controller
---> Controller得到数据和检查器之后,进行简单的数据判断之后将数据和检查器传递给M
--->Model对数据进行业务处理并且通过检查器通知VIEW更新视图
接下来我就贴出一个解决判断奇数偶数的程序,用到的是我这样理解的MVC模式.
大概长这样
---------------------------------------------------------------
先说大体构思
贴代码:
InputEvent.java
public interface InputEvent{ //数据输入时触发 VMC三者相关
public void inputEvent();
}
UpdateEvent.java
public interface UpdateEvent{ //需更新时触发 V M相关
public void updateEvent(String result);
}
InputEventNotifier.java
public class InputEventNotifier{
private InputEvent iEvent;
private boolean InputEventHappened;
public InputEventNotifier(InputEvent iEvent){
this.iEvent=iEvent;
InputEventHappened=false;
}
public void setInputEventHappened(){
InputEventHappened=true;
}
public void handleInputEvent(){
if(InputEventHappened){
iEvent.inputEvent(); //接口回调
}
}
}
UpdateEvent.java
public class UpdateEventNotifier{
private UpdateEvent uEvent;
private boolean UpdateEventHappened;
private String result;
public UpdateEventNotifier(UpdateEvent uEvent){
this.uEvent=uEvent;
UpdateEventHappened=false;
}
public void setUpdateEventHappened(){
UpdateEventHappened=true;
}
public void handleUpdateEvent(){
if(UpdateEventHappened){ //接口回调
uEvent.updateEvent(result);
}
}
public void setResult(String result){
this.result=result;
}
}
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class myMouseClickedListener extends MouseAdapter{ //鼠标监听器点击清空
public void mouseClicked(MouseEvent e){
JTextField JTF=(JTextField)e.getSource();
JTF.setText("");
}
}
public class myView extends JFrame implements InputEvent,UpdateEvent{
private myControl myC; //Controller成员
private String strFromUser; //来自用户的数据
private InputEventNotifier ien; //输入事件通知器
private UpdateEventNotifier uen; //更新视图事件通知器
private JTextField myJTFInput=new JTextField(20);
private JLabel myJL=new JLabel(" judgeResult : ");
private JTextField myJTFOutput=new JTextField(20);
public myView(){
ien=new InputEventNotifier(this);
uen=new UpdateEventNotifier(this);
myC=new myControl(); //初始化C,为后面衔接做准备
myC.setuenFromView(this.uen); //将 View的更新监听器 给 C
myJTFOutput.setEditable(false);
myJTFInput.setText("");
myJTFOutput.setText("");
myJTFInput.addMouseListener(new myMouseClickedListener()); //添加2种监听
myJTFInput.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e){
if(e.getKeyCode()==KeyEvent.VK_ENTER){
strFromUser=myJTFInput.getText();
ien.setInputEventHappened();
ien.handleInputEvent();
}
}
});
setSize(400,100);
JPanel myPane=new JPanel(new FlowLayout());
myPane.add(myJTFInput);
myPane.add(myJL);
myPane.add(myJTFOutput); //组件加入Panel
setContentPane(myPane); //set Panel
setVisible(true); //可见
}
public void inputEvent(){
myC.setStrFromView(strFromUser); //数据给C,并且通知C数据来了
myC.getien().setInputEventHappened();
myC.getien().handleInputEvent();
}
public void updateEvent(String result){ //根据来自Model的通知结果更新视图
if(result=="even"){
myJTFOutput.setText(" 偶数 ");
}else if(result=="odd"){
myJTFOutput.setText(" 奇数 ");
}else{
myJTFOutput.setText(" 输入有误 ");
}
}
public JTextField getJTFInput(){ //get set
return myJTFInput;
}
public JTextField getJTFOutput(){
return myJTFOutput;
}
public String getstrFromUser(){
return strFromUser;
}
}
myControl.java
public class myControl implements InputEvent{
private myModel myM;
private String strFromView;
private InputEventNotifier ien;
private UpdateEventNotifier uenFromView;
public myControl(){
ien=new InputEventNotifier(this);
myM=new myModel();
}
public void inputEvent(){
if(isDigit(strFromView)){ //数据基本判断
myM.setisString(true);
myM.setnumFromController(Integer.parseInt(strFromView));
}else{
myM.setisString(false);
}
myM.getien().setInputEventHappened(); //判断 传达数据并且通知Model有数据来了
myM.getien().handleInputEvent();
}
private boolean isDigit(String strNum){
return strNum.matches("[0-9]{1,}");
}
public void setuenFromView(UpdateEventNotifier uenFromView){
this.uenFromView=uenFromView; //来自view的uen给到Model
myM.setUenFromViewByController(this.uenFromView);
}
public void setStrFromView(String s){
strFromView=s;
}
public InputEventNotifier getien(){
return ien;
}
}
public class myModel implements InputEvent{
private InputEventNotifier ien; //自身的输入事件通知器
private UpdateEventNotifier uenFromViewByController; //来自view的更新事件通知器
private dataBean db; //数据bean
private boolean isEven;
private boolean isString;
private String result;
public myModel(){ //构造函数
ien=new InputEventNotifier(this);
isString=true;
db=new dataBean();
}
public void inputEvent(){ //得到输入通知后对数据判断并且通知视图进行更新
if(isString==true){
judgeNum();
if(isEven==true){
result="even";
}else{
result="odd";
}
}else{
result="wrong";
}
uenFromViewByController.setResult(result);
uenFromViewByController.setUpdateEventHappened();
uenFromViewByController.handleUpdateEvent();
}
private void judgeNum(){ //数字判断
if(db.getDataNum()%2==0){
isEven=true;
}else{
isEven=false;
}
}
public void setUenFromViewByController(UpdateEventNotifier u){
uenFromViewByController=u; //得到来自view的更新事件通知器
}
public void setisString(boolean s){ //C判断完用户输入是否为String的结果,以影响更新VIEW的选择
isString=s;
}
public void setnumFromController(int numFromController){
db.setDataNum(numFromController); //把来自C的数字存入后台数据中
}
public InputEventNotifier getien(){
return ien;
}
}
public class dataBean{
private int dataNum;
public void setDataNum(int dataNum){
this.dataNum=dataNum;
}
public int getDataNum(){
return dataNum;
}
}
public class mvcMain{
public static void main(String args[]){
myView my_view=new myView();
}
}
编译顺序:
javac
InputEvent.java
UpdateEvent.java
InputEventNotifier.java
UpdateEventNotifier.java
dataBean.java
myModel.java
myControl.java
myView.java
mvcMain.java
执行:
java mvcMain
结果:
左边的框输入数字之后 ENTER 就能看结果
(逃