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<Sender> list = new ArrayList<Sender>();

    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;
}
二、结构型模式:
三、行为型模式:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,290评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,107评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,872评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,415评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,453评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,784评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,927评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,691评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,137评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,472评论 2 326
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,622评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,289评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,887评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,741评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,316评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,490评论 2 348

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,629评论 18 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,598评论 18 399
  • 一. Java基础部分.................................................
    wy_sure阅读 3,805评论 0 11
  • 对象的创建与销毁 Item 1: 使用static工厂方法,而不是构造函数创建对象:仅仅是创建对象的方法,并非Fa...
    孙小磊阅读 1,967评论 0 3
  • 小编费力收集:给你想要的面试集合 1.C++或Java中的异常处理机制的简单原理和应用。 当JAVA程序违反了JA...
    八爷君阅读 4,578评论 1 114