ios mvc和mvvm的区别
首先是MVC,顾名思义,MVC是将Model, View和Controller分离,让彼此的职责(responsibility)能够明确的分开,这样不论是改M, V还是C,都可以确保另外两层可不用做任何修改,同时这样的分层也可以加强程式的可测试性(testability),View和Model基本上是相关的,但它们并不会有直接的相依关系,而是由Controller去决定Model产生的资料,然后丢给View去做呈现,也就是说,Controller是Model和View之间的协调者(coordinator),View和Model不能直接沟通,以确保责任的分离。而Controller可以只是一个系结Model和View的小类别,也可以是大到包含Workflow, Enterprise Services或是做为外部系统的Proxy Services等的逻辑系统,MVC各元件是可以分离的组件,也可以是分离的系统(当然要设计一些机制在相互沟通)
再来是MVVM,MVVM的架构一样是M, V分离,但中间是以VM (ViewModel)来串接,这个ViewModel比较像是View的一个代理程式,它负责直接对Model做沟通,而View可以透过一些机制(ex: Events, Two-way Databindings, ...)来和ViewModel沟通以取得资料或将资料抛给Model做存取等工作,ViewModel也可以作为和外部系统的代理程式,例如Web Service或是REST Service或是Enterprise Services等等,不过它和MVC不同的地方,就是ViewModel和View的黏合度比较高,因为View必须要透过ViewModel才可以取得Model,而ViewModel又必须要处理来自View的通知讯息,所以虽然职责一样分明,但是却不像MVC那样可以扩展到整个系统元件都能用。如果MVVM要和MVP比较的话,MVVM会比MVP更灵活一点。
接着是MVP,MVP一样也是职责分明,且Model与View分离的架构,但是这个P (Presenter)和ViewModel就很类似,不过就如同Presenter (主持人)这个字所代表的意义,所有主控View呈现的工作,都是由Presenter来做,而View本身只是Presenter所要使用的舞台而已,所以View原则上会相依于Presenter,但是为了要做到关注点分离(SoC原则),所以在View和Presenter间都会加入一个介面(ex: IView),然后以IoC的方式将View注射到Presenter中,而Presenter就使用介面所定义的方法去操控,而View就透过介面所定义的方法去呈现介面即可。但也因为受限于介面,所以Presenter只能依介面定义的动作去回应与处理,而不能再做更多的延伸功能,除非更改View的介面
由上面各个架构的讨论,我们可以得到以下的结果:
MVC 架构适合于大型系统,它可以分层且可以在实体层面切割为不同的机器或服务,只要彼此间具有适当的通讯协定即可。
MVVM 架构适合像XAML 这种与程式码无关(code ignorance) 的使用者介面设计,只要View 中下特定的指令与ViewModel 串接,就可以享有ViewModel 沟通的功能,而ViewModel 只需做一些特别的介面实作,即可平顺的和View 沟通。
MVP 架构适合集中由程式码决定View 动作的应用程式,而View 只需要实作特定的介面即可,不需要太复杂的工作,但Presenter 则可能会受限于View 介面的动作,而无法做更进一步对View 的控制。
spring mvc DispatcherServlet详解之interceptor和filter的区别
SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理,其他的作用比如通过它来进行权限验证,或者是来判断用户是否登陆,日志记录,或者限制时间点访问。
SpringMVC 中的Interceptor 拦截请求是通过HandlerInterceptor 来实现的。在SpringMVC 中定义一个Interceptor 非常简单,主要有两种方式,第一种方式是要定义的Interceptor类要实现了Spring 的HandlerInterceptor 接口,或者是这个类继承实现了HandlerInterceptor 接口的类,比如Spring 已经提供的实现了HandlerInterceptor 接口的抽象类HandlerInterceptorAdapter ;第二种方式是实现Spring的WebRequestInterceptor接口,或者是继承实现了WebRequestInterceptor的类。
HandlerInterceptor 接口中定义了三个方法,我们就是通过这三个方法来对用户的请求进行拦截处理的。
(1 )preHandle (HttpServletRequest request, HttpServletResponse response, Object handle) 方法。该方法将在请求处理之前进行调用。SpringMVC 中的Interceptor 是链式的调用的,在一个应用中或者说是在一个请求中可以同时存在多个Interceptor 。每个Interceptor 的调用会依据它的声明顺序依次执行,而且最先执行的都是Interceptor 中的preHandle 方法,所以可以在这个方法中进行一些前置初始化操作或者是对当前请求的一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。该方法的返回值是布尔值Boolean 类型的,当它返回为false 时,表示请求结束,后续的Interceptor 和Controller 都不会再执行;当返回值为true 时就会继续调用下一个Interceptor 的preHandle 方法,如果已经是最后一个Interceptor 的时候就会是调用当前请求的Controller 方法。
(2 )postHandle (HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView) 方法,由preHandle 方法的解释我们知道这个方法包括后面要说到的afterCompletion 方法都只能是在当前所属的Interceptor 的preHandle 方法的返回值为true 时才能被调用。postHandle 方法,顾名思义就是在当前请求进行处理之后,也就是Controller 方法调用之后执行,但是它会在DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作。postHandle 方法被调用的方向跟preHandle 是相反的,也就是说先声明的Interceptor 的postHandle 方法反而会后执行,这和Struts2 里面的Interceptor 的执行过程有点类型。Struts2 里面的Interceptor 的执行过程也是链式的,只是在Struts2 里面需要手动调用ActionInvocation 的invoke 方法来触发对下一个Interceptor 或者是Action 的调用,然后每一个Interceptor 中在invoke 方法调用之前的内容都是按照声明顺序执行的,而invoke 方法之后的内容就是反向的。
(3 )afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex) 方法,该方法也是需要当前对应的Interceptor 的preHandle 方法的返回值为true 时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。 我们的系统日志的拦截在这个方法中,可以记录日志的相关的参数,检测方法的执行。.
redis和mysql怎么一起在springmvc里面
一、mysql集成到springMVC中的方法:
1、在SRC目录下创建一个db-config.properties文件来存放我们的数据源配置信息:
db.url= jdbc:mysql:///springmvcdb?useUnicode=true&characterEncoding=utf8
db.username=root
db.password=root
db.dirverClass= com.mysql.jdbc.Driver
2、配置applicationContext.xml文件:
《?xml version=“1.0“encoding=“UTF-8“?》
《beans xmlns=“Redis 不是应用的共享内存,它只是一个内存服务器,就像 MySql 似的,我们需要将应用连接到它并使用某种“语言”进行交互,因此我们还需要一个连接工厂以及一个 Spring 和 Redis 对话要用的 RedisTemplate,这些都是 Redis 缓存所必需的配置,把它们都放在自定义的 CachingConfigurerSupport 中:
@EnableCaching
public class RedisCacheConfig extends CachingConfigurerSupport {
@Bean
public JedisConnectionFactory redisConnectionFactory() {
JedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory();
// Defaults
redisConnectionFactory.setHostName(“192.168.1.166“);
redisConnectionFactory.setPort(6379);
return redisConnectionFactory;
}
@Bean
public RedisTemplate《String, String》 redisTemplate(RedisConnectionFactory cf) {
RedisTemplate《String, String》 redisTemplate = new RedisTemplate《String, String》();
redisTemplate.setConnectionFactory(cf);
return redisTemplate;
}
@Bean
public CacheManager cacheManager(RedisTemplate redisTemplate) {
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
// Number of seconds before expiration. Defaults to unlimited (0)
cacheManager.setDefaultExpiration(3000); // Sets the default expire time (in seconds)
return cacheManager;
}
}
3、在 applicationContext.xml 中加入以下配置:
《context:component-scan base-package=“com.defonds.bdp.cache.redis“ /》
-iOS