设计模式是一套被反复使用的、多数人知晓的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。
对象的创建会消耗掉系统的很多资源,所以对对象的创建进行研究,从而能够高效地创建对象就是创建型模式要探讨的问题。这里有6个具体的创建型模式可供研究,它们分别是:
简单工厂模式(Simple Factory)
工厂方法模式(Factory Method)
抽象工厂模式(Abstract Factory)
建造者模式(Builder)
原型模式(Prototype)
单例模式(Singleton)
说明:严格来说,简单工厂模式不是GoF总结出来的23种设计模式之一。 GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式与抽象工厂模式。将简单工厂模式看为工厂方法模式的一种特例,两者归为一类。
在解决了对象的创建问题之后,对象的组成以及对象之间的依赖关系就成了开发人员关注的焦点,因为如何设计对象的结构、继承和依赖关系会影响到后续程序的维护性、代码的健壮性、耦合性等。对象结构的设计很容易体现出设计人员水平的高低,这里有7个具体的结构型模式可供研究,它们分别是:
外观模式/门面模式(Facade门面模式)
适配器模式(Adapter)
代理模式(Proxy)
装饰模式(Decorator)
桥梁模式/桥接模式(Bridge)
组合模式(Composite)
享元模式(Flyweight)
在对象的结构和对象的创建问题都解决了之后,就剩下对象的行为问题了,如果对象的行为设计的好,那么对象的行为就会更清晰,它们之间的协作效率就会提高,这里有11个具体的行为型模式可供研究,它们分别是:
模板方法模式(Template Method)
观察者模式(Observer)
状态模式(State)
策略模式(Strategy)
职责链模式(Chain of Responsibility)
命令模式(Command)
访问者模式(Visitor)
调停者模式(Mediator)
备忘录模式(Memento)
迭代器模式(Iterator)
解释器模式(Interpreter)
开闭原则(Open Close Principle):对扩展开放,对修改关闭。
里氏代换原则(Liskov Substitution Principle):只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。
依赖倒转原则(Dependence Inversion Principle):这个是开闭原则的基础,对接口编程,依赖于抽象而不依赖于具体。
接口隔离原则(Interface Segregation Principle):使用多个隔离的借口来降低耦合度。
迪米特法则(最少知道原则)(Demeter Principle):一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。
合成复用原则(Composite Reuse Principle):尽量使用合成/聚合的方式,而不是使用继承。继承实际上破坏了类的封装性,超类的方法可能会被子类修改。
简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类。
Spring中的BeanFactory就是简单工厂模式的体现,通过getBean函数传入一个唯一的标识来获得bean对象。
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
Spring中的FactoryBean就是典型的工厂方法模式。
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
Spring下默认的bean均为单例,当然也可以特殊配置为多例。
相当于cotroller层,用户调用一个请求,只要调用cotroller即可,cotroller里面有封装各种service。调用一个cotroller会把各个service逻辑整合好,不需要暴露各个服务相关的操作!
为其他对象提供一种代理以控制对这个对象的访问。
从结构上来看和装饰模式类似,但代理模式是控制,更像是一种对功能的限制,而装饰模式是增加职责。详解Java中的3种代理模式大家可以点击这里看 这篇文章
模板模式解决的问题:代码冗余,通过模板类+业务类作为参数解决。比如JDBCTemplate,模板方法处理创建连接、处理异常、释放资源等操作,业务类执行自己的sql
Spring MVC中引用了策略模式解决了不同类型的Request,可以共用DispatchServlet.doDispach()方法。
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mv = null;
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest);
// Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
applyDefaultViewName(processedRequest, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
程序会根据HandlerMapping中反馈的Handler的类型来选择对于的适配器接口的实现类,最终实现不同的处理逻辑
HandlerAdapter是一个接口,所有的扩展功能类都实现这个接口的 handler()方法,这样做的好处是节省内存,用到那种类型的Handler就加载哪个Handler,而不是一股脑的全加载进来
可以根据业务规则配置不同顺序的拦截器(责任链)
可以根据业务规则配置不同种类的拦截器(责任链)
Spring里面配置的拦截器,按照业务的需求来按照一定的顺序自由组合起来,实现特定的业务场景
喜欢就点个“在看”呗 ^_^