mvc例子 swift_swift mvc模型层怎么构建 - CSDN
  • 上一次我们讨论了iOS重构在MVC项目上的可行性,今天具体来讲基于MVC的项目重构步骤以及重构后的结构。   思考要解决的问题   回到项目重构的问题上来,我认为项目重构首先要想清楚的问题:   项目层级如何...

    上一次我们讨论了iOS重构在MVC项目上的可行性,今天具体来讲基于MVC的项目重构步骤以及重构后的结构。

     

    思考要解决的问题

     

    回到项目重构的问题上来,我认为项目重构首先要想清楚的问题:

     

    项目层级如何划分?

     

    大的业务场景有哪些?

     

    将UIViewController归类为View还是Controller?

     

    谁来负责网络请求,Model还是Controller?

     

    从Model中取得数据后Controller怎么把数据传递给View去展示?按照View层级逐级传递?是否需要使用ViewModel?

     

    Model的生命周期怎么控制?(全局Model和私有Model的划分)

     

    View层级结构越来越深时,怎么传递用户的交互操作?(毫无疑问NSNotification)

     

    UIViewController的划分

     

    本次重构中还是将UIViewController归类为C层,但是为了将UIViewController彻底和UIView分离开,命名上我们直接使用XXXController,我们对每一个XXXController设计了一个对应的名为的XXXContainerView的UIView对象,所有的view布局都会在这个XXXContainerView中完成.

     

    项目目录结构

     

    重构后的项目目录结构如下:

     

    一级目录 子目录 目录说明

    Macro 存放开发过程中所需的一些宏定义

    Category 存放不涉及业务,用来辅助开发的分类

    Tools 不同的业务工具类 存放涉及轻量级业务的处理类,比如根据不同业务格式化输出不同的字符串

    Views 不同的业务模块页面名 存放不同业务模块页面下的V

    Controllers 不同的业务模块页面名 存放不同业务模块页面下的C

    ViewModels 不同数据模块名 数据翻译层,将DataInfo数据翻译为View可直接展示的数据,但本次重构中由于时间因素不强制使用

    Model PublicModel 公用的全局Model,比如用户信息UserModel

    MoudleModel 单独某个模块使用的私有Model,只负责私有业务

    Services 不同的Service 提供底层服务,例如HttpService,SecurityService

     

    业务场景划分

     

    由于之前赶进度开发,没有做具体的功能拆分.本次重构之前使用了 StartUML 绘制了主要场景下的UML图,包括类图,时序图,流程图.

     

    强烈推荐新项目正式编码之前就完成这一步,并由前后端技术负责人主持进行UML评审.所有涉及到的业务Model的property以及public方法,所有DataInfo类的属性,甚至所有的Controller都会在绘制UML的过程中产出.当然,要想绘制所有场景下的UML图可能耗时比较久,一般来说只要绘制出主要交互场景即可.

     

    网络请求

     

    在手机端基本上所有的网络请求都是跟业务挂钩的,显然放在Model里更合适.至于请求完成后的回调就看个人习惯了,delegate或者block都是可行的.

     

    后续

     

    由于时间原因,并没有写出具体的示例代码,之后会针对一个示例场景,写出我理解中的各个MV(X)模式的参考代码,期待成文后与同行探讨.

     

    MVVM扩展

     

    放一张MVVM的示意图:

     

     

    看上去是不是很像MVP?只是多了View和ViewModel的双向绑定,这里强调一点,RAC不一定登陆MVVM,MVVM也不一定要使用RAC.想了解更多有关iOS开发(http://www.maiziedu.com/course/ios/),学习更多知识。

    展开全文
  • MVC程序设计实例

    2017-10-18 17:13:48
    欢迎访问我的 Github 主页 // // ModuleViewController.c // ExchangeSort // // Created by Mewlan Musajan on 10/18/17. // Copyright (c) 2017 Mewlan Musajan. All rights reserved. // ...int main(int

    欢迎访问我的 Github 主页

    //
    //  ModelViewController.c
    //  ExchangeSort
    //
    //  Created by Mewlan Musajan on 10/18/17.
    //  Copyright (c) 2017 Mewlan Musajan. All rights reserved.
    //
    
    #include <stdio.h>
    
    int main(int argc, char const *argv[])
    {
    	void loadModel();
    	loadModel();
    
    	return 0;
    }
    
    void loadModel()
    {
    	void loadView(int *p1, int *p2, int *p3);
    	int a, b, c, *p1, *p2, *p3;
    	p1 = &a;
    	p2 = &b;
    	p3 = &c;
    	loadView(p1, p2, p3);
    }
    
    void loadView(int *p1, int *p2, int *p3)
    {
    	printf("Please enter 3 integer:\n");
    	scanf("%d, %d, %d", p1, p2, p3);
    	void loadController(int *p1, int *p2, int *p3);
    	loadController(p1, p2, p3);
    	printf("3 numbers in descending order: %d, %d, %d\n", *p1, *p2, *p3);
    }
    
    void loadController(int *p1, int *p2, int *p3)
    {
    	void exchange(int *p1, int *p2, int *p3);
    	exchange(p1, p2, p3);
    }
    
    void exchange(int *p1, int *p2, int *p3)
    {
    	void swap(int *p1, int *p2);
    	if (*p1 < *p2)
    	{
    		swap(p1, p2);
    	}
    	if (*p1 < *p3)
    	{
    		swap(p1, p3);
    	}
    	if (*p2 < *p3)
    	{
    		swap(p2, p3);
    	}
    }
    
    void swap(int *p1, int *p2)
    {
    	int temp;
    	temp = *p1;
    	*p1 = *p2;
    	*p2 = temp;
    }



    展开全文
  • MVC案例一

    2019-09-05 13:35:37
    通过jsp页面,进行对数据库的增删改查 表结构: 1.根据表结构创建实体类Emp: public class Emp { private Integer empno; private String ename; private String job;... private Integer mgr;...

    通过jsp页面,进行对数据库的增删改查

    表结构:
    在这里插入图片描述

    1.根据表结构创建实体类Emp:

    public class Emp {
        private Integer empno;
        private String ename;
        private String job;
        private Integer mgr;
        private Date hiredate;
        private BigDecimal sal;
        private BigDecimal comm;
        private Integer deptno;
    
        public Emp() {
        }
    
        public Emp(Integer empno, String ename, String job, Integer mgr, Date hiredate, BigDecimal sal, BigDecimal comm, Integer deptno) {
            this.empno = empno;
            this.ename = ename;
            this.job = job;
            this.mgr = mgr;
            this.hiredate = hiredate;
            this.sal = sal;
            this.comm = comm;
            this.deptno = deptno;
        }
    
        public Integer getEmpno() {
            return empno;
        }
    
        public void setEmpno(Integer empno) {
            this.empno = empno;
        }
    
        public String getEname() {
            return ename;
        }
    
        public void setEname(String ename) {
            this.ename = ename;
        }
    
        public String getJob() {
            return job;
        }
    
        public void setJob(String job) {
            this.job = job;
        }
    
        public Integer getMgr() {
            return mgr;
        }
    
        public void setMgr(Integer mgr) {
            this.mgr = mgr;
        }
    
        public Date getHiredate() {
            return hiredate;
        }
    
        public void setHiredate(Date hiredate) {
            this.hiredate = hiredate;
        }
    
        public BigDecimal getSal() {
            return sal;
        }
    
        public void setSal(BigDecimal sal) {
            this.sal = sal;
        }
    
        public BigDecimal getComm() {
            return comm;
        }
    
        public void setComm(BigDecimal comm) {
            this.comm = comm;
        }
    
        public Integer getDeptno() {
            return deptno;
        }
    
        public void setDeptno(Integer deptno) {
            this.deptno = deptno;
        }
    
        @Override
        public String toString() {
            return "Emp{" +
                    "empno=" + empno +
                    ", ename='" + ename + '\'' +
                    ", job='" + job + '\'' +
                    ", mgr=" + mgr +
                    ", hiredate=" + hiredate +
                    ", sal=" + sal +
                    ", comm=" + comm +
                    ", deptno=" + deptno +
                    '}';
        }
    }
    

    2.写完实体类,我们开始写dao层(与数据库进行交互)

    接口

    public interface EmpDao {
        List<Emp> findAll();
        Emp findByEmpno(Integer empno);
        void add(Emp emp);
        void update(Emp emp);
        void delete(Integer empno);
    }
    

    在完成增删改查功能之前,需要先获取到连接(从连接池中)
    如果不懂,可以点开以下链接
    DBUtils工具类的使用
    数据库连接池

    public class DataSourceUtils {
    
        private static DruidDataSource dataSource;
    
        static {
            try {
                Properties properties = new Properties();
                InputStream is = DataSourceUtils.class.getClassLoader().getResourceAsStream("database.properties");
                properties.load(is);
    
                dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static DataSource getDataSourse(){
            return dataSource;
        }
    }
    

    然后创建接口的实现类:完成增删改查功能

    public class EmpDaoImpl implements EmpDao {
        @Override
        public List<Emp> findAll() {
            QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSourse());
            try {
                return qr.query("select * from emp", new BeanListHandler<Emp>(Emp.class));
            } catch (SQLException e) {
                e.printStackTrace();
                throw new RuntimeException("查找失败", e);
            }
        }
    
        @Override
        public Emp findByEmpno(Integer empno) {
            QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSourse());
            try {
                return qr.query("select * from emp where empno=?", new BeanHandler<Emp>(Emp.class), empno);
            } catch (SQLException e) {
                e.printStackTrace();
                throw new RuntimeException("查询失败", e);
            }
        }
    
        @Override
        public void add(Emp emp) {
            QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSourse());
            Object[] params = {emp.getEmpno(), emp.getEname(), emp.getJob(), emp.getMgr(), emp.getHiredate(), emp.getSal(), emp.getComm(), emp.getDeptno()};
            try {
                qr.update("insert into emp(empno, ename, job, mgr, hiredate, sal, comm, deptno) values(?,?,?,?,?,?,?,?)", params);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void update(Emp emp) {
            QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSourse());
            Object[] params = {emp.getEname(), emp.getJob(), emp.getMgr(), emp.getHiredate(), emp.getSal(), emp.getComm(), emp.getDeptno(), emp.getEmpno()};
            try {
                qr.update("update emp set ename=?, job=?, mgr=?, hiredate=?, sal=?, comm=?, deptno=? where empno=?", params);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void delete(Integer empno) {
            QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSourse());
            try {
                qr.update("delete from emp where empno=?", empno);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    

    3.然后开始写service层,service层的方法其实就是调用dao层的增删改查的方法,再加上一些业务逻辑的代码

    接口:

    public interface EmpService {
        List<Emp> queryAll();
        Emp queryByEmpno(Integer empno);
        void save(Emp emp);
        void modify(Emp emp);
        void delete(Integer empno);
    }
    

    实现类:
    这个只是简单的使用MVC模式实现增删该查功能,所以没有包含其他逻辑代码,只是简单调用了一下dao层的方法

    public class EmpServiceImpl implements EmpService {
    
        private EmpDao empDao = new EmpDaoImpl();
        @Override
        public List<Emp> queryAll() {
            return empDao.findAll();
        }
    
        @Override
        public Emp queryByEmpno(Integer empno) {
            return empDao.findByEmpno(empno);
        }
    
        @Override
        public void save(Emp emp) {
            empDao.add(emp);
        }
    
        @Override
        public void modify(Emp emp) {
            empDao.update(emp);
        }
    
        @Override
        public void delete(Integer empno) {
            empDao.delete(empno);
        }
    }
    

    到这,准备工作都已经做完了

    开始与前端进行交互

    1.1先查询数据展示到界面上,通过servlet把数据提交到前端

    @WebServlet(name = "ShowEmpServlet", value = "/showemp")
    public class ShowEmpServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //展示数据
            EmpService empService = new EmpServiceImpl();
            List<Emp> emps = empService.queryAll();
            //添加入域
            request.setAttribute("emps", emps);
            //转发,不能重定向,因为重定向会丢失数据
            request.getRequestDispatcher("/showemp.jsp").forward(request, response);
    
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    }
    

    1.2用于接收并展示数据的jsp,在页面上有增删改的操作对应的操作

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
    <html>
    <head>
        <title>展示员工</title>
    </head>
    <body>
        <table border="1" align="center">
            <tr>
                <th>员工编号</th>
                <th>姓名</th>
                <th>工作</th>
                <th>经理</th>
                <th>入职时间</th>
                <th>工资</th>
                <th>奖金</th>
                <th>部门</th>
                <th>
                    <a href="${pageContext.request.contextPath}/addemp.jsp">添加</a>
                </th>
            </tr>
            <c:forEach var="emp" items="${emps}">
                <tr>
                    <td>${emp.empno}</td>
                    <td>${emp.ename}</td>
                    <td>${emp.job}</td>
                    <td>${emp.mgr}</td>
                    <td><fmt:formatDate value="${emp.hiredate}" pattern="yyyy-MM-dd"></fmt:formatDate> </td>
                    <td>${emp.sal}</td>
                    <td>${emp.comm}</td>
                    <td>${emp.deptno}</td>
                    <td colspan="2">
                        <%--需要提供empno--%>
                        <a href="${pageContext.request.contextPath}/editemp?empno=${emp.empno}">修改</a>
                        <a href="${pageContext.request.contextPath}/deleteemp?empno=${emp.empno}" onclick="return confirm('确定要删除吗?')">删除</a>
                    </td>
                </tr>
            </c:forEach>
        </table>
    </body>
    </html>
    

    2.如果想要修改,会先跳转到编辑的servlet【先确定修改的是哪个员工】,然后再跳转到编辑的页面,最后再提交个真正写入数据库的servlet

    2.1先确定修改的是哪个员工,把数据提交给前端

    @WebServlet(name = "EditEmpServlet", value = "/editemp")
    public class EditEmpServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //设置编码,涉及到转发的,不需要设置编码,涉及重定向时,设置编码
            //response.setContentType("text/html;charset=utf-8");
            //获取empno,找到对象
            String empno = request.getParameter("empno");
            EmpService empService = new EmpServiceImpl();
            Emp emp = empService.queryByEmpno(Integer.parseInt(empno));
            //放入域
            request.setAttribute("emp", emp);
            //转发
            request.getRequestDispatcher("/editemp.jsp").forward(request, response);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    }
    

    2.2编辑页面

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>编辑员工</title>
    </head>
    <body>
        <h2>编辑员工</h2>
        <form action="${pageContext.request.contextPath}/updateemp" method="post">
            <table>
                <tr>
                    <td>员工编号</td>
                    <td>
                        <input type="text" name="empno" value="${emp.empno}" readonly="readonly">
                    </td>
                </tr>
                <tr>
                    <td>姓名</td>
                    <td>
                        <input type="text" name="ename" value="${emp.ename}">
                    </td>
                </tr>
                <tr>
                    <td>工作</td>
                    <td>
                        <input type="text" name="job" value="${emp.job}">
                    </td>
                </tr>
                <tr>
                    <td>经理</td>
                    <td>
                        <input type="text" name="mgr" value="${emp.mgr}">
                    </td>
                </tr>
                <tr>
                    <td>入职时间</td>
                    <td>
                        <input type="text" name="hiredate" value="${emp.hiredate}">
                    </td>
                </tr>
                <tr>
                    <td>工资</td>
                    <td>
                        <input type="text" name="sal" value="${emp.sal}">
                    </td>
                </tr>
                <tr>
                    <td>奖金</td>
                    <td>
                        <input type="text" name="comm" value="${empty emp.comm ? 0 : emp.comm}">
                    </td>
                </tr>
                <tr>
                    <td>部门</td>
                    <td>
                        <input type="text" name="deptno" value="${emp.deptno}">
                    </td>
                </tr>
                <tr>
                    <td>
                        <input type="submit" value="提交修改">
                    </td>
                </tr>
            </table>
        </form>
    </body>
    </html>
    

    2.3把更新后的数据写入数据库

    @WebServlet(name = "UpdateEmpServlet", value = "/updateemp")
    public class UpdateEmpServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //设置编码(一定要放在向对象中添加数据前面)
            request.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");
            //真正的提交数据
            Emp emp = new Emp();
            try {
                //因为数据中有日期类,日期类不能被格式化,需要自定义转换器
                ConvertUtils.register(new Converter() {
                    @Override
                    public <T> T convert(Class<T> aClass, Object o) {
                        if (o == null) {
                            return null;
                        }
                        if (o instanceof String) {
                            SimpleDateFormat[] sdfs = {
                                    new SimpleDateFormat("yyyy-MM-dd"),
                                    new SimpleDateFormat("yyyy/MM/dd"),
                                    new SimpleDateFormat("yyyy-MM-dd HH:ss:mm"),
                                    new SimpleDateFormat("yyyy/MM/dd HH:ss:mm")
                            };
    
                            String str = (String) o;
                            for (SimpleDateFormat sdf : sdfs) {
                                try {
                                    return (T) sdf.parse(str);
                                } catch (ParseException e) {
                                    e.printStackTrace();
                                    continue;
                                }
                            }
                        }
                        return null;
                    }
                }, Date.class);
    
                //转换BigDecimal
                ConvertUtils.register(new BigDecimalConverter(BigDecimal.ZERO),BigDecimal.class );
    
                //把数据封装入对象(使用BeanUtils工具类)
                BeanUtils.populate(emp, request.getParameterMap());
    
                EmpService empService = new EmpServiceImpl();
                empService.modify(emp);
                
                //更新过后再查看
                response.sendRedirect(request.getContextPath()+"/showemp");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    }
    

    3.添加与修改大同小异

    3.1先去前端编辑

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>添加员工</title>
    </head>
    <body>
    <h2>编辑员工</h2>
    <form action="${pageContext.request.contextPath}/addemp" method="post">
        <table>
            <tr>
                <td>员工编号</td>
                <td>
                    <input type="text" name="empno">
                </td>
            </tr>
            <tr>
                <td>姓名</td>
                <td>
                    <input type="text" name="ename">
                </td>
            </tr>
            <tr>
                <td>工作</td>
                <td>
                    <input type="text" name="job">
                </td>
            </tr>
            <tr>
                <td>经理</td>
                <td>
                    <input type="text" name="mgr">
                </td>
            </tr>
            <tr>
                <td>入职时间</td>
                <td>
                    <input type="text" name="hiredate">
                </td>
            </tr>
            <tr>
                <td>工资</td>
                <td>
                    <input type="text" name="sal">
                </td>
            </tr>
            <tr>
                <td>奖金</td>
                <td>
                    <input type="text" name="comm">
                </td>
            </tr>
            <tr>
                <td>部门</td>
                <td>
                    <input type="text" name="deptno">
                </td>
            </tr>
            <tr>
                <td>
                    <input type="submit" value="提交修改">
                </td>
            </tr>
        </table>
    </form>
    </body>
    </html>
    

    提交到servlet

    @WebServlet(name = "AddEmpServlet", value = "/addemp")
    public class AddEmpServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //设置编码
            response.setContentType("text/html;charset=utf-8");
            request.setCharacterEncoding("utf-8");
            //获取数据
            try {
                Emp emp = new Emp();
    
                ConvertUtils.register(new Converter() {
                    @Override
                    public <T> T convert(Class<T> aClass, Object o) {
                        if (o == null){
                            return null;
                        }
                        if (o instanceof String) {
                            String date = (String) o;
                            SimpleDateFormat[] sdfs = {
                                    new SimpleDateFormat("yyyy-MM-dd"),
                                    new SimpleDateFormat("yyyy/MM/dd"),
                                    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"),
                                    new SimpleDateFormat("yyyy/MM/dd HH:mm:ss")
                            };
                            for (SimpleDateFormat sdf : sdfs) {
                                try {
                                    return (T) sdf.parse(date);
                                } catch (ParseException e) {
                                    e.printStackTrace();
                                    continue;
                                }
                            }
    
                        }
                        return null;
                    }
                }, Date.class);
    
    			//转换BigDecimal
                ConvertUtils.register(new BigDecimalConverter(BigDecimal.ZERO),BigDecimal.class );
    			
                BeanUtils.populate(emp, request.getParameterMap());
    
                EmpService empService = new EmpServiceImpl();
                empService.save(emp);
    
                //重定向到展示页面
                response.sendRedirect(request.getContextPath() + "/showemp");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    }
    

    4.删除

    直接删除

    @WebServlet(name = "DeleteEmpServlet", value = "/deleteemp")
    public class DeleteEmpServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //获取empno
            String empno = request.getParameter("empno");
            EmpService empService = new EmpServiceImpl();
            empService.delete(Integer.parseInt(empno));
            //重定向
            response.sendRedirect(request.getContextPath() + "/showemp");
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    }
    
    
    展开全文
  • MVC简介 MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写。 MVC开始是存在于桌面程序中的,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码...

    MVC简介

    MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写。
    MVC开始是存在于桌面程序中的,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。比如一批统计数据可以分别用柱状图、饼图来表示。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。

    MVC编程模式

    MVC模式虽然是iOS编程中使用最广泛的模式,但论起复杂程度,MVC模式可以算是众多设计模式之首。通常情况下,MVC模式需要综合使用target-action模式、delegate模式、Notification或KVO模式等。

    • Model(模型)表示应用程序核心(比如数据库记录列表),通常模型对象负责在数据库中存取数据。
    • View(视图)显示数据(数据库记录),通常视图是依据模型数据创建的。
    • Controller(控制器)处理输入(写入数据库记录),通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。

    MVC原理可简化为下图:
    在这里插入图片描述

    • Controller和View之间可以通信,Controllor通过outlet(输出口)控制View,View可以通过target-action、delegate或者data source(想想UITableVeiwDatasource)来和Controller通信;
    • Controller在接收到View传过来的交互事件(View就是完成让人和程序的交互的呀,比如按B1按钮)之后,经过一些判断和处理,把需要Model处理的事件递交给Model处理(比如刚才的例子中的保存到数据库),Controller对Model使用的是API;
    • Model在处理完数据之后,如果有需要,会通过Notification或者KVO的方式告知Controller,事件已经处理完,Controller再经过判断和处理之后,考虑下一步要怎么办(是默默无闻的在后台操作,还是需要更新View,这得看Controller的“脸色”行事)。这里的无线天线很有意思,Model只负责发送通知,具体谁接收这个通知并处理它,Model并不关心,这一点非常重要,是理解Notification模式的关键。
    • Model和View之间不直接通信!
      以上摘自这篇博客

    注册登陆实例

    • 新建M V C三个文件夹(需要几个View建几套文件夹)
    • 新建一个名为VView的类,继承自UIView(以登陆界面为例)
    • 新建一个名为MModel的类,继承自NSObject
    • 拖到相应的文件夹下,注册界面同上
    • 新建一个跳转的界面,用于登陆后跳转

    完成以后应该是这样:
    在这里插入图片描述
    按照MVC的思想,VView中应该写两个textField和两个button(以登陆界面为例),写好后的代码如下:

    #import <UIKit/UIKit.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface VView : UIView
    
    @property (nonatomic, strong) UIButton *loadBtn;
    @property (nonatomic, strong) UIButton *registerBtn;
    @property (nonatomic, strong) UITextField *nameTextField;
    @property (nonatomic, strong) UITextField *passTextField;
    
    - (void)InitView; //view初始化
    
    @end
    
    #import "VView.h"
    
    @implementation VView
    
    - (void)InitView {
        
        _loadBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        [_loadBtn setFrame:CGRectMake(80, 400, 100, 50)];
        [_loadBtn setTitle:@"load" forState:UIControlStateNormal];
        [_loadBtn setTitleColor:[UIColor blackColor] forState: UIControlStateNormal];
        [self addSubview:_loadBtn];
        
        _registerBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        [_registerBtn setFrame:CGRectMake(230, 400, 100, 50)];
        [_registerBtn setTitle:@"register" forState:UIControlStateNormal];
        [_registerBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [self addSubview:_registerBtn];
        
        _nameTextField = [[UITextField alloc] initWithFrame:CGRectMake(50, 200, 300, 50)];
        _nameTextField.layer.masksToBounds = YES;
        _nameTextField.layer.cornerRadius = 5;
        _nameTextField.layer.borderWidth = 2;
        _nameTextField.layer.borderColor = [UIColor blackColor].CGColor;
        _nameTextField.placeholder = @"nameWord";
        [self addSubview:_nameTextField];
        
        _passTextField = [[UITextField alloc] initWithFrame:CGRectMake(50, 280, 300, 50)];
        _passTextField.layer.masksToBounds = YES;
        _passTextField.layer.cornerRadius = 5;
        _passTextField.layer.borderWidth = 2;
        _passTextField.layer.borderColor = [UIColor blackColor].CGColor;
        _passTextField.secureTextEntry = YES;
        _passTextField.placeholder = @"passWord";
        [self addSubview:_passTextField];
        
    }
    

    会发现button里没有添加target-action方法,这是因为target-action方法需要设置一个target对象,在这个对象里调用action方法。按照MVC的思想,V里面不进行数据处理,而是要在C里面统一调控由C还是M来处理数据。本例中,我们是在C里面处理,所以我把targe-action方法写到C里面。

    按照MVC的思想,M主要用于数据的处理,所以在这个案例中我将存放账号和密码的数组放入M中。

    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface MModel : NSObject
    
    @property (nonatomic, strong) NSMutableArray *nameArr;
    @property (nonatomic, strong) NSMutableArray *passArr;
    
    - (void)modelInit;
    //- (void)addName:(NSString *)name Pass:(NSString *)pass;
    
    @end
    
    #import "MModel.h"
    
    @implementation MModel
    
    - (void)modelInit {
        
        _nameArr = [[NSMutableArray alloc] init];
        _passArr = [[NSMutableArray alloc] init];
        [_nameArr addObject:@"123"];
        [_passArr addObject:@"456"];
        
    }
    

    接下来就是C了,登陆注册需要使用协议来传值,传值的操作我在这里就不解释了,不懂的朋友可以看看这篇博客,由于我在VView和MModel中定义的方法为实例方法,所以我需要实例化VView和MModel来调用这些方法:

    #import <UIKit/UIKit.h>
    #import "RViewController.h"
    #import "VView.h"
    #import "MModel.h"
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface ViewController : UIViewController
    <RegisterDelegate>
    
    @property (nonatomic, strong) VView *myView;
    @property (nonatomic, strong) MModel *myModel;
    
    @end
    
    #import "ViewController.h"
    #import "newViewController.h"
    #import "RViewController.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        
        _myView = [[VView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
        [_myView InitView];
        [_myView.loadBtn addTarget:self action:@selector(pressLoad) forControlEvents:UIControlEventTouchUpInside];
        [_myView.registerBtn addTarget:self action:@selector(pressRegister) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:_myView];
        
        _myModel = [[MModel alloc] init];
        [_myModel modelInit];
        
    }
    
    - (void)pressLoad {
        
        for (int i = 0; i < _myModel.nameArr.count; i++) {
            if ([_myView.nameTextField.text isEqualToString: _myModel.nameArr[i]] && [_myView.passTextField.text isEqualToString:_myModel.passArr[i]]) {
                newViewController *new = [[newViewController alloc] init];
                [self presentViewController:new animated:NO completion:nil];
            }
        }
    }
    
    - (void)pressRegister {
        
        RViewController *RegistViewController = [[RViewController alloc] init];
        RegistViewController.registerDelegate = self;
        [self presentViewController:RegistViewController animated:NO completion:nil];
        
        
    }
    
    - (void)passName:(NSString *)name passPass:(NSString *)pass {
        
        [_myModel.nameArr addObject:name];
        [_myModel.passArr addObject:pass];
        
    }
    

    到这里登陆界面就写完了,注册界面原理和它一样,我就只放代码不进行过多的讲解了

    因为没有数据的改变,所以RModel里没有任何东西

    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface RModel : NSObject
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    #import "RModel.h"
    
    @implementation RModel
    
    
    @end
    
    

    RView:

    
    #import <UIKit/UIKit.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface RView : UIView
    
    @property (nonatomic, strong) UIButton *loadBtn;
    @property (nonatomic, strong) UIButton *registerBtn;
    @property (nonatomic, strong) UITextField *nameTextField;
    @property (nonatomic, strong) UITextField *passTextField;
    
    - (void)InitView; //view初始化
    
    @end
    
    #import "RView.h"
    
    @implementation RView
    
    - (void)InitView {
        
        _loadBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        [_loadBtn setFrame:CGRectMake(80, 400, 100, 50)];
        [_loadBtn setTitle:@"back" forState:UIControlStateNormal];
        [_loadBtn setTitleColor:[UIColor blackColor] forState: UIControlStateNormal];
        [self addSubview:_loadBtn];
        
        _registerBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        [_registerBtn setFrame:CGRectMake(230, 400, 100, 50)];
        [_registerBtn setTitle:@"Ok" forState:UIControlStateNormal];
        [_registerBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [self addSubview:_registerBtn];
        
        _nameTextField = [[UITextField alloc] initWithFrame:CGRectMake(50, 200, 300, 50)];
        _nameTextField.layer.masksToBounds = YES;
        _nameTextField.layer.cornerRadius = 5;
        _nameTextField.layer.borderWidth = 2;
        _nameTextField.layer.borderColor = [UIColor blackColor].CGColor;
        _nameTextField.placeholder = @"nameWord";
        [self addSubview:_nameTextField];
        
        _passTextField = [[UITextField alloc] initWithFrame:CGRectMake(50, 280, 300, 50)];
        _passTextField.layer.masksToBounds = YES;
        _passTextField.layer.cornerRadius = 5;
        _passTextField.layer.borderWidth = 2;
        _passTextField.layer.borderColor = [UIColor blackColor].CGColor;
        _passTextField.secureTextEntry = YES;
        _passTextField.placeholder = @"passWord";
        [self addSubview:_passTextField];
        
    }
    
    

    RViewController:

    #import <UIKit/UIKit.h>
    #import "RView.h"
    #import "RModel.h"
    
    NS_ASSUME_NONNULL_BEGIN
    @protocol RegisterDelegate <NSObject>
    
    - (void)passName:(NSString *)name passPass:(NSString *)pass;
    
    @end
    
    @interface RViewController : UIViewController
    
    @property (nonatomic, strong) RView *myView;
    @property (nonatomic, strong) RModel *myModel;
    @property id <RegisterDelegate> registerDelegate;
    
    @end
    
    #import "RViewController.h"
    #import "ViewController.h"
    
    @interface RViewController ()
    
    @end
    
    @implementation RViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        
        _myView = [[RView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
        [_myView InitView];
        [_myView.loadBtn addTarget:self action:@selector(pressLoad) forControlEvents:UIControlEventTouchUpInside];
        [_myView.registerBtn addTarget:self action:@selector(pressRegister) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:_myView];
        
        _myModel = [[RModel alloc] init];
        
    }
    
    - (void)pressLoad {
        
        [self dismissViewControllerAnimated:NO completion:nil];
        
    }
    
    - (void)pressRegister{
        
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"你已成功注册!" preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *sure = [UIAlertAction actionWithTitle:@"sure" style:UIAlertActionStyleCancel handler:^(UIAlertAction *sure) {
            if ([self->_registerDelegate respondsToSelector:@selector(passName:passPass:)]) {
                [self->_registerDelegate passName:self->_myView.nameTextField.text passPass:self->_myView.passTextField.text];
            }
             [self dismissViewControllerAnimated:NO completion:nil];
        }];
        [alert addAction:sure];
        [self presentViewController:alert animated:NO completion:nil];
        
    }
    
    
    展开全文
  • MVC系列之 ----登录实例

    千次阅读 热门讨论 2014-12-03 17:36:20
    MVC系列之——入门 为大家简单的介绍一下MVC的工作原理,这篇文章通过一个实例来为大家看看他到底是怎么一步一步的进行!  首先让我们新建一个工程,选择web 下的ASP.NET MVC3 Web应用程序,然后选择空模板,视图...
  • 简单介绍MVC,和一个具体的Mvc例子

    万次阅读 2013-10-11 23:08:44
    MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写。  MVC 结构图    mvc的优点:   下面做一个简单的MVC模式下的用户登录。 1 建立动态web工程,名称为Struct2_login。 ...
  • 它是AFNetworking的作者写的Swift形式,今天先介绍一下,利用pod导入AFNetworking,SVProgressHUD,MJRefresh等第三方实现刷新数据、加载更多、网络请求,同时使用了MVC的模式进行界面搭建,随后研究Alamofire实现...
  • 本篇主要是通过总结Swift中3种控制视图的方法来简单介绍一下MVC架构中的VC。
  • From MVC to MVVM in Swift

    2019-03-01 20:36:33
    一开始跟从苹果公司的建议,坚持使用MVC设计模式似乎是一个好主意。但是在这个应用持续发展的情况下,它里面的一些逻辑开始变得复杂,修改代码时总是伴随着一种忧虑的感觉,修改一部分代码的问题时害怕引起其他部分...
  • 本文不仅为大家提供一套原生RadioButton组件,而且还学习SwiftUI数据流的最佳案例 实战需求 RadioButton 是Windows 窗体的控件,为用户提供由两个或多个互斥选项组成的选项集。常用于男女性别、是否开关等用于场景。...
  • MVC案例之DAO层实现

    2019-03-13 11:38:00
    文章目录MVC案例之DAO层实现操作步骤概述实际操作遇到的问题 MVC案例之DAO层实现 操作步骤 概述 加入C3P0数据源 C3P0 数据库驱动的jar包 编写DAO,JdbcUtils工具类和CustomerDAO接口 提供CustomerDAO接口的实现...
  • 1、新建一个类库项目,我们暂且命名为Swift.MVC. 2、新建MvcHandler和UrlRoutingModule 3、新建一个空的Web项目测试Swift.MVC 二、版本二:完善MvcHandler和UrlRoutingModule 1、UrlRoutingModule的完善 2、...
  • Swift MVVM

    千次阅读 2019-08-16 11:18:18
    用OC开发的时候用的MVC架构模式,所以想在Swift中试试MVVM架构模式 都说MVVM是MVC改进而来,因为MVC的Controller太庞大了,所以给他减减重,就新建了一种ViewModel类,它继承于NSObject, 从ViewController里抽出UI...
  • MVC是很多人学习App开发学习的第一种设计模式,深入理解其的含义与组成部分与相互配合,对学习开发有着至关重要的最要。本文简要介绍MVC设计模式与ViewController的相关概念,并说明Application Delegate的相关使用...
  • 在DeviceNumberRequestable.swift文件中: import Foundation //请求结果 enum DeviceNumberRequestResult<T>{ case success<T> case failure(Error) } //模型遵循Codable协议 struct ...
  • GitHub上Swift开源项目!

    万次阅读 2017-02-04 19:10:16
    swift-open-project这里汇集了目前为止最为流行的Swift开源项目,选取SwiftGuide中的开源部分,这里将每周对项目进行总结,如果大家有推荐的可以联系thinkloki@gmail.com,或者issues,欢迎Star、Fork。感谢...
  • MVC框架

    千次阅读 2015-10-29 21:58:32
    就iOS而言 MVC无处不在 是基础 是核心 可以说它是设计模式 但更多的说是框架 这两天认真研究了一下MVC设计模式,在iOS开发中这个算是重点中的重点了,如果对MVC模式不理解或者说不会用,...
  • 因为对swift的认识还不够深入,公司需要换到swift编程,只是看了几个swift写的别人的工程,自我感觉良好. 在项目启动时,也是为了赶进度就按照以前OC的做法(面向对象编程),只是觉得只是语法不同而已,不过尔尔. 逐渐在...
  • 观察者模式 swift

    2017-03-17 11:55:33
    观察者模式 - Observer在观察者模式里,一个对象在状态变化的时候会通知另一个对象。参与者并不需要知道其他对象的具体是干什么的 ...在 MVC 里,观察者模式意味着需要允许 Model 对象和 View 对象进行交流,而不能有直
  • 天天说MVC,尤其对于做iOS开发的,更是口头禅,因为Apple已经为我们量身定制了适合iOS开发的MVC架构。那么什么是MVC? 对于iOS的程序猿来说,MVC人人都说自己会用,但是呢实际开发过程中很多人都会有这样的体会,...
1 2 3 4 5 ... 20
收藏数 1,216
精华内容 486
关键字:

mvc例子 swift