应届生面试要点总结(12)设计模式相关

单例模式双重检查锁

public static Singleton getInstance() {  
  
if (instance == null) { // 这种方式采用双锁机制,安全且在多线程情况下能保持高性能  
  
synchronized(Singleton.class) {  
  
if (instance == null)  
  
instance = new Singleton();  
  
}  
  
}  
  
return instance;  
  
}  

单例模式(枚举实现)

enum danli {

INSTANCE;

private String string;

public String getString() {

return string;

}

public void setString(String string) {

this.string = string;

}

}

danli one = danli.INSTANCE;

one.setString("hello");

System.out.println(one.getString());

danli two = danli.INSTANCE;

System.out.println(one == two); // true

懒汉式

public class Singleton {

private static Singleton instance;

private Singleton () {}

public static synchronized Singleton getInstance() { // 必须加锁 synchronized 才能保证单例,但加锁会影响效率

if (instance == null) {

instance = new Singleton(); // 第一次调用才初始化,避免内存浪费

}

return instance;

}

}

饿汉式

public class Singleton {

private static Singleton instance = new Singleton(); // 类加载时就初始化,浪费内存

private Singleton () {}

public static Singleton getInstance() { // 没有加锁,执行效率会提高

return instance;

}

}

静态内部类

public class Singleton {

private static class SingletonHolder {

private static final Singleton INSTANCE = new Singleton();

}

private Singleton () {}

public static final Singleton getInstance() {

return SingletonHolder.INSTANCE;

}

}

单例模式:序列化,又反序列化后,不是同一个对象,但可加上readResolve()函数,并在方法体上写上return instance;这样就是同一个对象了。用反射获得私有构造函数,然后用constructor.newInstance弄的两个对象也不是同一个对象,为了避免这个漏洞,可在私有构造函数中加上if (null != instance) return new RuntimeException();

代理设计模式:代理类和委托类有相同的接口,一个代理类的对象与一个委托类的对象关联。代理类的对象本身并不真正实现服务,而是通过调用委托类对象相关方法提供特定的服务。

代理是在内部生成一个代理对象,构造函数参数为空。装饰的构造函数参数有一个对象,就是对这个对象进行装饰。

用代理模式,代理类可以对它的用户隐藏一个对象的具体信息。因此,使用代理模式的时候,我们常常在一个代理类中创建一个对象的实例。当我们使用装饰模式时,我们通常的做法是将原始对象作为一个参数传递给装饰者的构造器。装饰模式:新增行为;代理模式:控制访问。

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。

java用observer接口和obserable类实现观察者模式:创建观察者类observable类;创建观察者observer接口;对于被观察者,添加他的观察者void add Observer(Observer o):该方法把观察者对象添加到观察者对象列表中,当观察时间发生时,调用setchange()来设置一个内部标志,注明数据发生了变化;notifyobservers()调用观察者列表中所有observer的update方法,通知他们数据发生变化,只有在setchange被调用以后,notifyobservers才会调用update;对于观察者类,实现observer接口的唯一方法update。

观察者模式:推模型:传递的信息更多更具体。拉模型:目标对象在通知观察者时,只传递少量信息,由观察者主动到目标对象中获取,相当于观察者从目标对象中拉数据,update方法传递目标对象的引用为拉模型observer接口observable类。

观察者和发布-订阅:虽然两种模式都存在订阅者和发布者(具体观察者可以认为是订阅者,具体目标可以认为是发布者),但是观察者模式是由具体目标调度,发布-订阅者是由调度中心调度,所以观察者模式的订阅者和发布者之间存在依赖,而发布-订阅就不会。

工厂方法模式适合,凡是出现了大量的产品需要创建,并且有公共的接口,可以通过工厂方法模式进行创建,一个工厂里,不同方法创建不同的类。

抽象工厂:工厂方法模式有一个问题就是,类的创建依赖于工厂,也就是想要扩展程序,必须对工厂类进行修改,用抽象工厂,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不用改以前的代码,一个工厂生产一个具体的对象。

建造者模式,工厂模式提供的是创建单个对象的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象。

原型模式,将一个对象作为原型,对其进行复制克隆,产生一个和原对象类似的新对象。

适配器模式:将某个类的接口转化为客户端期望的另一个接口表示。

接口的适配器模式:有时候我们写的接口种有多个抽象方法,当我们写接口的实现类时,必须实现改接口的所有方法,但并不是所有的方法都是我们必须的,有时候只需要某一些,此时,我们可以借助于一个抽象类,该抽象类实现该接口,实现所有的方法,我们不和原始接口打交道,只和抽象类联系,所以我们写一个类继承抽象类,重写我们需要的方法就行。

类的适配:当希望将一个类转换为满足另一个接口时,创建一个新类,继承原有的类,实现新的接口。

对象的适配:当希望将一个对象转化为满足于另一个新接口的对象时,创建一个wrapper类,持有原类的实例,在wrapper类的方法种,调用实例的方法。

外观模式facede:为解决类于类之间的依赖关系,将它们的关系放在facede类中。

组合模式,将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

迭代器模式:定义:提供一种方法访问一个容器对象中各个元素,而又不暴露该对象的内部细节。适用场景:迭代器和集合共生死。优点:简化遍历。

策略模式:所有策略都来自于同一个接口,一个策略一个类,接口为参数,传入具体策略(具体类对象),利用多态。一个类的行为或其算法可以在运行时更改。

jdk中的设计模式单例,runtime类;静态工厂,Integer i = Integer.valueOf(int or String);迭代器,Collection.iterator();原型,clone();适配器,inputstreamReader和outputstreamWrite;桥接,jdbc抽象实现分离;装饰模式,Reader和bufferReader;代理,jdk动态代理;组合,某个类型方法同时也接受自身类型参数java.util.list.addall(collection);抽象工厂,创建新对象的方法,返回具体对象的方法proxy.newproxyinstance;解释器,通常定义了一个语言语法,java.util.pattern。

设计模式(大类5种):创建者模式:工厂方法,抽象工厂,单例,建造者,原型。结构型模式:适配器,桥接,装饰,代理,外观,组合,享元模式。行为型模式:策略,模板方法,责任列,观察者,命令,备忘录,访问者,中介者,解析器,状态,迭代器模式。还有并发行模式和线程池模式。

猜你喜欢

转载自blog.csdn.net/SEUSUNJM/article/details/86588820