目录
4、单例模式(Singleton)
4-1、什么是单例模式
4-2、模式结构
4-3、懒汉式和饿汉式
4-4、单例模式的应用场景
3、抽象工厂模式(AbstractFactory)
3-1、什么是抽象工厂模式
3-2、模式结构
3-3、优缺点
2、工厂模式(Factory)
2-1、什么是工厂模式
2-2、模式结构
2-3、优缺点
1、代理模式 (Proxy)
1-1、什么是代理模式?
1-2、模式结构
1-3、代理模式分类:
1-4、趣例引用
1-5、优缺点
一个类只有一个实例,且该类能自行创建这个实例。
单例模式有 3 个特点:
单例类只有一个实例对象;该单例对象必须由单例类自行创建;单例类对外提供一个访问该单例的全局访问点;第 1 种:懒汉式单例
该模式的特点是类加载时没有生成单例,只有当第一次调用 getlnstance 方法时才去创建这个单例。线程不安全,可以通过加锁的方式实现线程安全,代码如下:
注意:如果编写的是多线程程序,则不要删除上例代码中的关键字 volatile 和 synchronized,否则将存在线程非安全的问题。如果不删除这两个关键字就能保证线程安全,但是每次访问时都要同步,会影响性能,且消耗更多的资源,这是懒汉式单例的缺点。
public class LazySingleton { private static volatile LazySingleton instance=null; //保证 instance 在所有线程中同步 private LazySingleton(){} //private 避免类在外部被实例化 public static synchronized LazySingleton getInstance() { //getInstance 方法前加同步 if(instance==null) { instance=new LazySingleton(); } return instance; } }第 2 种:饿汉式单例
该模式的特点是类一旦加载就创建一个单例,保证在调用 getInstance 方法之前单例已经存在了。 饿汉式单例在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以是线程安全的,可以直接用于多线程而不会出现问题。
public class HungrySingleton { private static final HungrySingleton instance=new HungrySingleton(); private HungrySingleton(){} public static HungrySingleton getInstance() { return instance; } }前面分析了单例模式的结构与特点,以下是它通常适用的场景的特点。
在应用场景中,某类只要求生成一个对象的时候,如一个班中的班长、每个人的身份证号等。当对象需要被共享的场合。由于单例模式只允许创建一个对象,共享该对象可以节省内存,并加快对象访问速度。如 Web 中的配置对象、数据库的连接池等。当某类需要频繁实例化,而创建的对象又频繁被销毁的时候,如多线程的线程池、网络连接池等。为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品。
抽象工厂是对 工厂模式的一种延申:工厂模式中,一个工厂对应一个产品;抽象工厂就是 一个工厂对应多个产品;由此引申出产品足和产品级的概念;
抽象工厂模式除了具有工厂方法模式的优点外,其他主要优点如下。
可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。当增加一个新的产品族时不需要修改原代码,满足开闭原则。其缺点是:当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。
定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。
工厂方法模式的主要优点有:
用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;其缺点是:每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。
工厂模式 对比 简单工厂:
简单工厂就是只创建一个工厂类,根据客户端传入不同参数进行逻辑判断,实例化不同产品;但是会违背开闭原则;工厂模式 优化了开闭原则,通过创建多个工厂,每个工厂创建不同的产品;解决了开闭原则的问题,实际是把开闭问题交给了客户端,也就是把逻辑判断的部分由客户端完成;为其他对象提供一种代理,以控制对这个对象的访问。
追求者 代理人 被追求者
static void Main(string[] args) { SchoolGirl jiaojiao = new SchoolGirl(); jiaojiao.Name = "李娇娇"; Proxy daili = new Proxy(jiaojiao); daili.GiveDolls(); daili.GiveFlowers(); daili.GiveChocolate(); Console.Read(); }代理模式的主要优点有:
代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;代理对象可以扩展目标对象的功能;代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度;其主要缺点是:
在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;增加了系统的复杂度;