单例模式
- (1)饿汉式 开发用这种方式。
//饿汉式(声明静态对象时就初始化对象)
public class Singleton
{
// 1,私有构造函数
private Singleton()
{
}
// 2,创建本类对象
private static Singleton mInstance = new Singleton();
// 3,对外提供公共的访问方法
public static Singleton getInstance()
{
return mInstance ;
}
}
- (2)懒汉式 (多线程的问题)
//懒汉式,单例的延迟加载模式(线程不安全)
public class Singleton
{
// 1,私有构造函数
private Singleton()
{
}
// 2,声明一个本类的引用
private static Singleton s;
// 3,对外提供公共的访问方法
public static Singleton getInstance()
{
if (s == null)
{
// 线程1,线程2...多线程时可能会创建多个对象
s = new Singleton();
}
return s;
}
}
多线程安全,但是效率低:
public class Singleton {
private static Singleton instance;
private Singleton (){}
// 每次调用都同步,这样会消耗不必要的资源
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
双重锁定:
public class Singleton
{
// 1,私有构造函数
private Singleton()
{
}
// 2,声明一个本类的引用
private static Singleton s;
// 3,对外提供公共的访问方法,加锁,解决多线程同时访问会创建多个对象的问题
public static Singleton getInstance()
{
if (s == null)
{
synchronized (Singleton.class)
{
if (s == null)
{
s = new Singleton();
}
}
}
return s;
}
}
- (3)静态内部类方式实现
public class Singleton {
private Singleton() {}
private static class SingletonHolder
{
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance()
{
return SingletonHolder.INSTANCE;
}
}
这种方式,第一次加载Singleton这个类时,不会加载SingletonHolder。只有第一次调用 getInstance()时才会初始化实例INSTANCE。即保证了线程安全,也保证了单例对象的唯一性,同时也延迟了单例的初始化,是推荐使用的单例模式实现方式。
简单工厂模式
- A:简单工厂模式概述
- 又叫静态工厂方法模式,它定义一个具体的工厂类负责创建一些类的实例
- B:优点
- 客户端不需要在负责对象的创建,从而明确了各个类的职责
- C:缺点
- 这个静态工厂类负责所有对象的创建,如果有新的对象增加,或者某些对象的创建方式不同,就需要不断的修改工厂类,不利于后期的维护
举例:
class AnimalFactory {
private AnimalFactory() {}
public static Animal createAnimal(String animalName)
{
if(“dog”.equals(animalName))
{
return new Dog();
}
else if(“cat”.equals(animale))
{
return new Cat();
}else
{
return null;
}
}
}
工厂方法模式
- A:工厂方法模式概述
- 工厂方法模式中抽象工厂类负责定义创建对象的接口,具体对象的创建工作由继承抽象工厂的具体类实现。
- B:优点
- 客户端不需要在负责对象的创建,从而明确了各个类的职责,如果有新的对象增加,只需要增加一个具体的类和具体的工厂类即可,不影响已有的代码,后期维护容易,增强了系统的扩展性
- C:缺点
- 需要额外的编写代码,增加了工作量
- D: 举例
动物抽象类:public abstract Animal { public abstract void eat(); } 工厂接口:public interface Factory {public abstract Animal createAnimal();} 具体狗类:public class Dog extends Animal {} 具体猫类:public class Cat extends Animal {} 开始,在测试类中每个具体的内容自己创建对象,但是,创建对象的工作如果比较麻烦,就需要有人专门做这个事情,所以就知道了一个专门的类来创建对象。发现每次修改代码太麻烦,用工厂方法改进,针对每一个具体的实现提供一个具体工厂。 狗工厂:public class DogFactory implements Factory { public Animal createAnimal() {…} } 猫工厂:public class CatFactory implements Factory { public Animal createAnimal() {…} }
适配器模式
-
类适配器模式
- a.什么是类适配器
- 在使用监听器的时候, 需要定义一个类事件监听器接口.
- 通常接口中有多个方法, 而程序中不一定所有的都用到, 但又必须重写, 这很繁琐.
- 适配器简化了这些操作, 我们定义监听器时只要继承适配器, 然后重写需要的方法即可.
- b.适配器原理
- 适配器就是一个类, 实现了监听器接口, 所有抽象方法都重写了, 但是方法全是空的.
- 适配器类需要定义成抽象的,因为创建该类对象,调用空方法是没有意义的
- 目的就是为了简化程序员的操作, 定义监听器时继承适配器, 只重写需要的方法就可以了.
- a.什么是类适配器
-
对象适配器模式(常用)
- 通常情况下,客户端可以通过目标类的接口访问它所提供的服务。但有时,现有的类虽然可以满足客户类的功能需要,但是它所提供的接口不一定是客户类所期望的,这可能是因为现有类中方法名与目标类中定义的方法名不一致等原因所导致的。
- 在适配器模式中可以定义一个包装类,包装不兼容接口的对象,这个包装类指的就是适配器(Adapter),它所包装的对象就是适配者(Adaptee),即被适配的类。
- 适配器可以使由于接口不兼容而不能交互的类可以一起工作。
装饰模式
- 什么是装饰模式
- 动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
- 使用装饰器模式的时候,通常的做法是将原始对象作为一个参数传给装饰者的构造器。
- 案例
- java里的BufferedInputStream的设计
- public BufferedInputStream(InputStream in),BufferedInputStream包装了InputStream,扩展了功能
代理模式
- 给某一个对象提供一个代理,并由代理对象控制对原对象的引用
- 当使用代理模式的时候,通常在一个代理类中创建一个对象的实例
- 代理模式对代理的对象施加控制,并不提供对象本身的增强功能