Java Design Pattern

java初学,整理的也很是简陋,只是为了加强记忆,不喜勿喷,但是有误尽量指出。
Java设计模式
主要是创建型模式的学习,太渣,其他几个模式还没敢看。
Write Ahead:设计模式几大原则
a、Open Close Principle,即对扩展开放,对修改关闭,使得程序有好的扩展性,为了达到这样一个效果,需要使用接口和抽象类。
b、Dependence Inversion Principle,是Open Close Principle的基础,针对接口编程,依赖接口而不依赖于具体。
c、Liskov Substitution Principle,
d、Interface Segregation Principle,
e、Demeter Principle,
f、Composite Reuse Principle,
一、创建型模式:

  1. 工厂方法模式(Factory Method):大量对象,共同接口--普通工厂模式,多个工厂模式以及静态工厂模式
    共同接口
    public interface Sender {
    void send();
    }
    多个对象:对象一
    public class MailSender implements Sender {
    @Override
    public void send() {
    System.out.println("I am mail sender!");
    }
    }
    多个对象:对象二
    public class SmsSender implements Sender {
    @Override
    public void send() {
    System.out.println("I am sms sender!");
    }
    }
    11、普通工厂模式
    public class SendFactory {
    public Sender produce(String type){
    if("mail".equals(type)){
    return new MailSender();
    }
    if("sms".equals(type)){
    return new SmsSender();
    }
    else
    System.out.println("请输入正确的类型!");
    return null;
    }
    }

12、多个工厂模式
public class MultiFactory{
public Sender produceMail(){
return new MailSender();
}

public Sender produceSms(){
    return new SmsSender();
}

}
13、静态工厂模式,不需要创建实例
public class StaticFactory{
public static Sender produceMail(){
return new MailSender();
}
public static Sender produceSms(){
return new SmsSender();
}
}
缺点:只有一个工厂类,想要扩展程序必须对工厂类进行修改,因此类的创建依赖于工厂类,这违背了闭包原则。所以有了抽象工厂模式。

  1. 抽象工厂模式:多个工厂,开闭原则,只加不修改
    提供一个工厂接口,即抽象工厂
    public interface Provider {
    Sender produce();
    }
    多个工厂:工厂一
    public class MailFactory implements Provider {
    @Override
    public Sender produce() {
    return new MailSender();
    }
    }
    多个工厂:工厂二
    public class SmsFactory implements Provider {
    @Override
    public Sender produce() {
    return new SmsSender();
    }
    }
    优点:想要新增一个发即时消息的功能,只需一个实现Sender接口的实现类和一个实现provider接口的实现类即可,避免修改现有代码。
  2. 单例模式(Singleton),在一个JVM中,某对象只有一个实例存在。
    a、有些类的创建比较频繁,对于大型对象,是很大的系统开销。
    b、省去了new操作符,降低了系统内存的使用频率,减轻GC(Garbage Collection)压力。
    c、有些类控制着整个流程(例如某交易所的核心交易引擎控制着交易流程),如果该类允许创建多个的话,整个系统就完全乱了。
    单例模式必须保证线程安全
    1⃣️饿汉式:线程安全,但是类加载时就实例化,而且由于构造函数私有,无法继承
    public class Singleton {
    /**
    • 类加载时自行实例化
      /
      private static final Singleton instance = new Singleton();
      /
      *
    • 私有构造函数
      /
      private Singleton(){
      }
      /
      *
    • 唯一外部可访问接口,线程安全
      /
      public static Singleton getInstance(){
      return instance;
      }
      }
      2⃣️懒汉式:存在线程安全的问题
      public class LazySingleton {
      private static LazySingleton instance = null;
      private LazySingleton(){
      }
      /
      *
    • 非线程安全
      /
      public static LazySingleton getInstance(){
      if(instance == null){
      instance = new LazySingleton();
      }
      return instance;
      }
      }
      3⃣️线程安全的懒汉式:效率低
      public class LazySingleton {
      private static LazySingleton instance = null;
      private LazySingleton(){
      }
      /
      *
    • 加锁,线程安全,效率低
      /
      public synchronized static LazySingleton getInstance(){
      if(instance == null){
      instance = new LazySingleton();
      }
      return instance;
      }
      }
      4⃣️双重校验锁-线程安全锁懒汉式:由于JVM内存模型,无序优化,导致双重验证锁问题(DCL,Double-checked-locked)
      public class LazySingletonDoubleChecked {
      private static LazySingletonDoubleChecked instance;
      /
      私有构造函数/
      private LazySingletonDoubleChecked(){
      }
      /
      双重检查加锁的代码/
      public static LazySingletonDoubleChecked getInstance(){
      if(instance==null){
      synchronized(Singleton.class){
      if(instance==null){
      instance = new LazySingletonDoubleChecked();
      }
      }
      }
      return instance;
      }
      }
      /
      *
  • 1.线程1进入getInstance() 方法。
  • 2.由于此时instance 为null,线程1进入synchronized 块。
  • 3.此时线程1被线程2预占。
  • 4.线程2进入getInstance()方法。
  • 5.由于此时instance仍null,线程2试图获取锁。由于线程1持有该锁,线程2将进入阻塞。
  • 6.线程2被线程1预占,线程1执行
  • 7.由于实例仍为null,线程1创建一个LazySingletonDoubleChecked对象并将其引用赋值给instance。
  • 8.线程1退出synchronized块并从getInstance() 方法返回实例。
  • 9.线程1被线程2预占。
  • 10.线程2获取锁并检查instance是否为null。
  • 11.由于instance非null的,就咩有创建第二个Singleton对象,由线程1创建的一个尚未执行构造函数的对象被返回。
  • 假设为代码行instance =new LazySingletonDoubleChecked(); 执行了下列伪代码:
  • memory = allocate(); //为LazySingletonDoubleChecked对象分配memory.
  • instance = memory; //此时instance不是null, 但是并没有被initialized.
  • constructorSingleton(instance);//Invoke constructor进行初始化.
    /
    5⃣️volatile-双重校验锁-线程安全锁懒汉式:
    public class LazySingletonDoubleChecked {
    private volatile static LazySingletonDoubleChecked instance;
    /
    私有构造函数/
    private LazySingletonDoubleChecked(){
    }
    /
    双重检查加锁的代码/
    public static LazySingletonDoubleChecked getInstance(){
    if(instance==null){
    synchronized(Singleton.class){
    if(instance==null){
    instance = new LazySingletonDoubleChecked();
    }
    }
    }
    return instance;
    }
    }
    下面只需要对initialized对象进行加锁,缩小了锁的范围
    public class LazySingletonDoubleChecked {
    private volatile static LazySingletonDoubleChecked instance = null;
    private Boolean initialized = false;
    public LazySingletonDoubleChecked getInstance(){
    if(!initialized){
    synchronized (initialized){
    if(instance == null){
    instance = new LazySingletonDoubleChecked();
    }
    initialized = true;
    return instance;
    }
    }
    return instance;
    }
    }
    6⃣️枚举式:
    7⃣️登记式-懒汉式单例:6⃣️7⃣️暂不研究
    使用内部类来维护单例的实现,JVM内部的机制能够保证当一个类被加载的过程是线程互斥的。这样第一次调用getInstance时,JVM能够帮我们保证instance只被创建一次,并且会保证把赋值给instance的内存初始化完毕
    public class SingletonInnerClass {
    private SingletonInnerClass(){
    }
    /
    *
    *使用内部类来维护单例的实现
    /
    private static class SingletonFactory{
    private static SingletonInnerClass instance = new SingletonInnerClass();
    }
    public static SingletonInnerClass getInstance(){
    return SingletonFactory.instance;
    }
    /
    如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */
    public Object readResolve() {
    return getInstance();
    }
    }
  1. 建造者模式(Builder Method):创建复合类型,相对于工厂模式,将多个功能集合到一个类中
    public class Builder {
    List list = new ArrayList();

    public void produceMailSender(){
    list.add(0, new MailSender());
    }

    public void produceSmsSender(){
    list.add(0, new SmsSender());
    }
    }

  2. 原型模式(Prototype Method):一个对象作为原型,对其进行克隆,复制产生一个和原对象类似的新对象
    只需要实现Cloneable接口,覆写clone方法
    public class Prototype implements Cloneable {

    @Override
    public Object clone() throws CloneNotSupportedException {
    /**
    * super.clone()调用的是object.clone方法(native)
    */
    Prototype proto = (Prototype) super.clone();
    return proto;
    }
    }
    浅复制:浅复制不彻底。基本数据类型的变量重新创建,而引用类型指向原对象所指向的内存。
    深复制:就是深复制进行了完全彻底的复制。将一个对象复制后,基本数据类型和引用类型,都重新创建。
    public class Prototype implements Cloneable, Serializable {

    private static final long serialVersionUID = 1L;
    private String str;

    private SerializableObject serializableObject;

    /* 浅复制 */
    public Object clone() throws CloneNotSupportedException {
    Prototype proto = (Prototype) super.clone();
    return proto;
    }

    /* 深复制 */
    public Object deepClone() throws IOException, ClassNotFoundException {

     /* 写入当前对象的二进制流 */
     ByteArrayOutputStream bos = new ByteArrayOutputStream();
     ObjectOutputStream oos = new ObjectOutputStream(bos);
     oos.writeObject(this);
    
     /* 读出二进制流产生的新对象 */
     ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
     ObjectInputStream ois = new ObjectInputStream(bis);
     return ois.readObject();
    

    }

    public String getStr() {
    return str;
    }

    public SerializableObject getSerializableObject() {
    return serializableObject;
    }

    public void setStr(String str) {
    this.str = str;
    }

    public void setSerializableObject(SerializableObject serializableObject) {
    this.serializableObject = serializableObject;
    }
    }

class SerializableObject implements Serializable {
private static final long serialVersionUID = 1L;
}
二、结构型模式:
三、行为型模式:

你可能感兴趣的:(Java Design Pattern)