单例模式
概念:这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方法。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
注意:
单例类只能有一个实例;
单例类必须自己创建自己的唯一的实例;
单例类必须给所有其他对象提供这一实例。
优点:
在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例;避免对资源的多重占用。
缺点:
没有接口,不能继承,与单一职责原则冲,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
工厂模式
概念:这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。我们在创建对象时不会对客户暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建工程延迟到子类进行。
主要解决:主要解决接口选择的问题。
何时使用:我们明确的计划不同条件下创建不同实例时。
如何解决:让其子类实现工厂接口,反悔的也是一个抽象的产品。
关键代码:创建过程在其子类执行。
优点:
一个调用者想创建一个对象,只要知道其名称就可以了;
扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以;
屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖,这并不是什么好事。
注意事项:作为一种创建类模式,有任何需要生成复杂对象的地方,都可以使用工厂方法模式,有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过new就可以完成创建的对象,无需使用工厂模式。
观察者模式
概念:当对象间存在一对多关系时,则使用观察者模式。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。
关键代码:在抽象类里有一个ArrayList存放观察着们
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新
如何解决:使用面向对象技术,可以将这种依赖关系弱化
主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作
优点:
观察者和被观察者是抽象耦合的;
建立一套触发机制。
缺点:
如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间;
如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃;
观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
策略模式
概念:定义了家族算法,分别封装起来,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户
意图:定义一系列的算法,把他们一个个封装起来,并且使他们可相互替换
主要解决:在有多种算法相似的情况下,使用if…else…所带来的复杂和难以维护
关键代码:实现同一个接口
优点:
算法可以自由切换;
避免使用多重条件判断;
扩展性良好。
缺点:
策略类会增多;
所有策略类都需要对外暴露。
装饰者模式
概念:允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增增多,子类会很膨胀。
何时使用:在不想增加很多子类的情况下扩展类。
如何解决:将具体功能职责划分,同时继承装饰者模式
关键代码:
Component类充当抽象角色,不应该具体实现;
修饰类引用和继承component类,具体扩展类重写父类方法
优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以扩展一个实现类的功能
缺点:多层装饰比较复杂
使用场景:扩展一个类的功能;动态增加功能,动态撤销。