前言:封装、继承、多态(面向对象)!编程的重要思想,万变不离其中!
每个开发人员,都有一种同病相怜:“产品经理的频繁该需求,导致程序猿呐喊彷徨!更改需求,轻者:不吃中餐的修改;重者,废寝忘食通宵的修改;更甚者:代码推倒重来,直接吐血”!
然而,大家都明白:“产品的需求变动是必然的,只是或多或少而已!”;既然,“变是避免不了的,那么就让我们尽力为变做些准备,防范于未然!”,于是乎:封装,继承,多态的重要性就体现出来了,设计模式的重要性也体现出来了!下面我们来谈谈设计模式:
1、简单工厂模式
概念: 解决了到底要实例化谁的问题:创建一个工厂类(在其中包含一个静态方法,用来传递判断业务种类)对实现同一个接口的对象进行实例化!结合switch一起使用,根据业务不同,对不同的业务类实例化!
a、业务抽象类(产品接口)
b、各个业务的实现类(产品实现类)
c、工厂类/工具类(包括唯一个根据业务创建不同实例的静态方法)
优点:明确了各自的职责和权利,有利于整个软件结构体系的优化!
缺点:由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则!
使用场景:对上层的使用者隔离对象的创建过程;对象的创建过程比较复杂,使用者不容易掌握;对象的创建需要满足某些条件时;
2、策略模式(Strategy)
概念: 定义了算法家族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户。
a) 提供公共接口或抽象类,定义需要使用的策略方法。(策略抽象类)
b) 多个实现的策略抽象类的实现类。(策略实现类)
c) 环境类,对多个实现类的封装,提供接口类型的成员量,可以在客户端中切换。
优点:
(1)策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免代码重复。
(2)使用策略模式可以避免使用多重条件(if-else)语句。多重条件语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重条件语句里面,比使用继承的办法还要原始和落后。
缺点:
(1)客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道算法或行为的情况。
(2)由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观。
3、开放-封闭原则(OCP)
概念:类、模块、函数等应该可以扩展,但是不可以修改,这种思想就是一种开放-封闭原则。
a)面对需求,对程序的改动是通过增加代码进行的,而不是更改现有的代码。
b)在我们最初编写代码的时候,假设变化不会发生变化。当发生变化的时候,我们就创建抽象来隔离以后发生的同类变化。
c)开放-封闭原则是面向对象设计的核心所在
优点:为设计带来了巨大的好处,也就是可维护,可扩展,可复用,灵活性好。
缺点:对应用程序中的每个部分都刻意的进行抽象是一个非常不好的注意,拒绝不成熟的抽象。
4、单例模式(Singleton)
概念: 保证一个类仅有一个实例,并提供一个访问它的全局问点。(通常我们可以让一个全局变量使得一个对象被访问,但是它不能防止你实例化多个对象。一个最好的办法就是,让类自身保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个可以访问该实例的方法。)
a)构造方法私有华(让其被private修饰),这就堵死了外界利用new 创建此类实例的可能。
b) 添加此类引用的静态成员变量,并为其实例化(实例化的顺序不同就出现了“饿汉式和懒汉式”)
c)在类中提供静态方法,用来供外界获取本类的实例。
饿汉式:在类被加载的时候就将自己初始化,也叫静态初始化;(线程安全:因为静态成员变量只随类的加载而加载仅一次!因此,实例也只被初始化一次。)
懒汉式:在需要的时候才初始化类的实例成为懒汉式。(当出现多个线程同时访问时,会实例化多个对象,也叫做线程不安全。所以需要在静态方法中加synchronized修饰,用来达到线程同步!)
优点:
(1)、提供了对唯一实例的受控访问。
(2)、由于在系统内存中只存在一个对象,因此可以 节约系统资源,当 需要频繁创建和销毁的对象时单例模式无疑可以提高系统的性能。
(3)、允许可变数目的实例。
(4)、避免对共享资源的多重占用。
缺点:
(1)、不适用于变化的对象,如果同一类型的对象总是要在不同的用例场景发生变化,单例就会引起数据的错误,不能保存彼此的状态。
(2)、由于单利模式中没有抽象层,因此单例类的扩展有很大的困难。
(3)、单例类的职责过重,在一定程度上违背了“单一职责原则”。
适用场景:
(1)、 单例模式只允许创建一个对象,因此节省内存,加快对象访问速度,因此对象需要被公用的场合适合使用,如多个模块使用同一个数据源连接对象等等。
(2)、创建对象时耗时过多或者耗资源过多,但又经常用到的对象。
(3)、有状态的工具类对象。
(4)、频繁访问数据库或文件的对象。