您的位置:68399皇家赌场 > 集群主机 > java-23种设计格局(笔记一)

java-23种设计格局(笔记一)

发布时间:2019-10-06 04:55编辑:集群主机浏览(126)

    适配器格局

    主旨情想:始建贰个适配器类能够同有的时候间具备有现成类的一颦一笑,和期待的接口。

    图片 1对象适配器格局

    现实贯彻进度:分为三种情形

    1. 类适配器:适配器类达成梦想的接口,承接现成的类已获得他的表现。
    2. 目的适配器:适配器类完结梦想的接口,并保有现成类的实例,通超过实际例调用方法。指标都以同一的。

    结构性形式:7种

    ----设计形式学习笔记-20170109---

    6.1类的适配器情势

    类的适配器形式核心绪想就是:有三个Source类,具备贰个方法,待适配;目的接口是Targetable;通过Adapter类,将Source的效率扩张到Targetable里。
    身体力行代码:

    public class Source {
        public void method1() {  
            System.out.println("this is original method!");  
        }  
    }
    
    public interface Targetable {
        /* 与原类中的方法相同 */
        public void method1();
    
        /* 新类的方法 */
        public void method2();
    }
    
    public class Adapter extends Source implements Targetable {
        public void method2() {
            System.out.println("this is the targetable method!");
        }
    }
    
    测试类:
    public class AdapterTest {
        public static void main(String[] args) {
            Targetable target = new Adapter();
            target.method1();
            target.method2();
        }
    }
    

    原型格局

    核激情想:行使Object类的clone方法,快速复制对象。

    图片 2原型方式

    21、访谈者格局(Visitor)

    1.分手对象的数据结构与表现的艺术,通过这种分离可完结为被访谈者动态增加新的操作而无需做别的修改的功力;
    2.优点:数据结构与作为(操作)分离,加多新的操作方便;
    3.受制:适用于数据结构相对安静的系统,增多新的数据结构特别不方便;

    • from :
    8、装饰情势

    在不必改动原类文件和运用持续的气象下,动态地扩充叁个对象的功能。它是透过创办叁个装进对象,也便是装修来包裹真实的对象。

    装修情势的特色:
    (1) 装饰对象和踏踏实实对象有同等的接口。这样顾客端对象就会以和真实性对象相同的办法和装潢对象交互。
    (2) 装饰对象包蕴二个忠实对象的援用(reference)
    (3) 装饰对象接受全数来自顾客端的央求。它把那几个乞请转载给真实的指标。
    (4) 装饰对象能够在转会那一个央浼从前或之后扩展一些增大效率。那样就保障了在运维时,不用修改给定目的的构作育足以在外表扩张附加的功能。在面向对象的宏图中,经常是因而持续来促成对给定类的功用增加。承接不可能成功那点,继承的效用是静态的,不能够动态增加和删除。

    演示代码:

    实体接口:
    public interface Sourceable {
        public void method();
    }
    实体类:
    public class Source implements Sourceable {
    
        @Override
        public void method() {
            System.out.println("the original method!");
        }
    }
    装饰类:
    public class Decorator implements Sourceable {
    
        private Sourceable source;
    
        public Decorator(Sourceable source) {
            super();
            this.source = source;
        }
    
        @Override
        public void method() {
            System.out.println("before decorator!");
            source.method();
            System.out.println("after decorator!");
        }
    }
    
    测试类:
    public class DecoratorTest {
    
        public static void main(String[] args) {
            //(1) 装饰对象和真实对象有相同的接口。这样客户端对象就能以和真实对象相同的方式和装饰对象交互。
            //(2) 装饰对象包含一个真实对象的引用(reference)
            //(3) 装饰对象接受所有来自客户端的请求。它把这些请求转发给真实的对象。
            //(4) 装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能。
            //    在面向对象的设计中,通常是通过继承来实现对给定类的功能扩展。
            //    继承不能做到这一点,继承的功能是静态的,不能动态增删。
            Sourceable source = new Source();
            Sourceable obj = new Decorator(source);
            obj.method();
        }
    }
    

    虚幻工厂形式

    宗旨理想:工厂方法基础上,让二个工厂生产一类对象。

    图片 3抽象工厂格局

    现实落到实处进度:在工厂方法的功底上,在二个具体育工作厂中贯彻生育不一致产品的措施。能够直达方便生产三个“产品簇”的指标。

    4、建造者形式

    1.好像于工厂方法,只是工厂方法创造八个类,而建造者形式开创三个满足须要的指标,对象只怕相比较复杂是七个对象的会集;

    1. 设计形式的分类
      八种创立者形式 : 单例格局,工厂方法情势,抽象工厂形式,建造者情势,原型方式
      多种结构型格局 : 适配器情势,装饰器情势,代理格局,外观方式,桥接情势,组合方式,享元格局
      十一种表现情势 : 计策形式,模板方法情势,观望者情势,迭代子格局,义务链情势,命令形式,备忘录情势,状态情势,访谈者方式,中介者方式,解释器格局
      --并发型形式 : Future方式,Master_worker形式,Guarded Suspension方式,不改变格局,生产者花费者情势 
      --线程池情势 : HS/HA半联合/半异步情势,L/F领导者跟随者格局

    2. 设计情势六大规格
      开闭原则 : 对扩张开放,修改关闭
      里氏代换原则 : 任何基类出现的地点,子类一定可以出现
      依附倒置原则 : 依赖抽象,不借助于具体
      接口隔绝原则 : 使用多个隔开分离的接口,并不是单个接口包涵持有办法
      迪米特法规 : 实体尽量少和任何实体发生相互成效
      合成复用原则 : 尽量使用合成聚合实际不是持续

    3. 23种设计情势
        1. 两种创设者格局
          1. 单例方式 : JVM中只开创多少个实例存在,一再使用,严酷单例须求调节线程安全,反体系化创造对象
          2. 工厂方法形式
            1. 家常工厂情势 : 营造二个工厂类,对落实平等接口的类进行实例制造,多少个实例共用二个工厂方法
            2. 三个厂子方法情势 : 对平日工厂立异,各类实例的成立对应三个厂子方法
            3. 静态工厂方法情势 : 对八个厂子方法方式立异,将艺术设置为静态的,不再必要创制工厂实例
          3. 华而不实工厂格局 : 抽象工厂情势,创建五个工厂类,那样只要要求扩展新的功效,只需追加新的工厂类,没有要求修改原有代码
          4. 建造者形式 : 建造者是创办理并答复合对象,工厂情势创制单个产品
          5. 原型形式 : 对多个已有目的的复制产生三个和原对象类似的新对象,通过clone
            1. 浅复制 : 基本数据类型的变量会被重复创造,引用类型大概指向原对象 (Object.clone正是浅拷贝)
            2. 深复制 : 基本数据类型和援引类型被重复创制(写入读出二进制流产生新对象)
        2. 各类结构型格局
          1. 适配器情势
            1. 类的适配器格局 : 接口Targetable具有和A同样的情势,并有新的适配方法,类Adapter承接A达成Targetable
            2. 对象的适配器情势 : 和类适配器分歧的是,持有A的实例实际不是继承A
            3. 接口的适配器格局 : 解决一时候并不想实现接口中的全数的不二等秘书技,让抽象类B落成接口C,其余的兑现类只须要承袭B
          2. 装饰器方式 : 给三个对象动态扩张新的作用,装饰对象B达成被点缀对象A一样的接口,而且B持有A的实例,顾客更关切棉被服装饰后的效用
          3. 代理方式 : 类Proxy完结被代理的类A一样的接口,并持有A的实例,完结类似装饰器形式,但顾客更关爱被代理的对象功用
          4. 外观情势 : 化解类与类之间的重视关系,将别的的类组合在一道
          5. 桥接方式 : 把东西和现实贯彻分开,使得两岸能够独立变化 (参照他事他说加以考察JDBC的不等数据库驱动加载)
          6. 重组方式 : 多个对象组合在一道开展操作
          7. 享元方式 : 达成指标的分享(参照他事他说加以考察数据库连接池的落到实处,commons-pool开源达成)
        3. 十一种表现情势
          1. 父类和子类
            1. 宗旨格局 : 多个子类达成同三个接口,客商按自个儿的选料采用分歧的兑现,如排序接口,具体完结快排,堆排等
            2. 模板方法格局 : 抽象类定义主方法,子类承袭抽象类,接纳完成父类的主意,通过调用父类达成对子类的调用
          2. 多个类之间
            1. 观望者格局 : 旁观者先订阅,被旁观者变化时通报列表内的观看者
            2. 迭代子格局 : 用于遍历聚聚集的目的,如集结,Iterator持有遍历对象实例,对其开展逐项访谈
            3. 职务链形式 : 三个实例对象调用自身的实例去管理二个职务,然后递归,始终会有七个目的去处理这几个职务,这些查找链不限于链表和树等
            4. 下令方式 : 实现和呼吁分开,如controller和service层的分离
          3. 类的情状
            1. 备忘录情势 : 原始类A创制备忘类B保存在C中,B保存A的属性,C只可以增加产量无法改改
            2. 状态格局 : 类A有两样情况Status,分化的图景一样方法对应分裂的行事

    6.2对象的适配器情势

    指标的适配器情势的基本思路和类的适配器方式同样,只是将Adapter类作修改成Wrapper,这一次不一而再Source类,而是全体Source类的实例,以落成缓和包容性的难题。
    躬行实践代码:

    public class Wrapper implements Targetable {
    
        private Source source;
    
        public Wrapper(Source source) {
            super();
            this.source = source;
        }
    
        @Override
        public void method2() {
            System.out.println("this is the targetable method!");
        }
    
        @Override
        public void method1() {
            source.method1();
        }
    }
    
    测试代码:
    public class AdapterTest {
        public static void main(String[] args) {
            Source source = new Source();
            Targetable target = new Wrapper(source);
            target.method1();
            target.method2();
        }
    }
    

    建造者情势

    核心绪想:概念三个建筑进程,具体的建造放在子类在那之中,那样能够运用同一的建筑进程构造差异的实例。

    图片 4建造者形式

    22.中介者格局(Mediator)

    1.裁减类之间的耦合度;
    2.中介者类持有七个类的实例,有中介者类维护类之间的关系;

        4. 经过中间类
          1. 采访者情势 : 分离对象数据结谈判作为的不二秘技,化解为现存类A新扩大功效,不能够修改A的代码的情景,瑕玷是不适用数据结构易于变动的风貌
          2. 中介者情势 : 为裁减类的耦合性,只需保险另外类和中间类的涉及,无需类之间互相持有实例对象
          3. 解释器方式 : 类似编写翻译器,正则表达式实现,使用景况受限
      4. --并发型方式
        1. Future情势 : 进步响应速度
        2. Master_worker情势 : 子职务分配,升高响应速度 
        3. Guarded Suspension情势 : 队列缓冲,非立即管理,幸免因为乞请太多而咽气
        4. 不改变形式 : 类似String/Double...不须要一块,线程安全
        5. 劳动者花费者情势 : 减轻两个间的属性差
        --6. Java 3种并发完毕
          1. Thread : 直接使用Thread和Runnable
          2. Executors和瑟维斯s : 线程池才能来调整应用程序的产出,线程数日常和事务有关于cpu不相干,须求上下文切换实现产出,职分从最早到完工作时间间是不牢固的,奉行进度中供给抢占cpu
          3. ForkJoin框架和相互流 : cpu数来决定并行,并发多少不会超越cpu的并发数
      5. --线程池方式
        1. HS/HA 半联袂/半异步情势 : 分为三层同步层(Queue的一路),队列层(Queue),异步层(Thread),类似生产者花费者;数据拷贝,语境切换必要多余的开销
        2. L/F 领导者跟随者情势 : 每一种线程分享贰个事件源,并在五个情景切换leader、follower和processor;leader接受事件,状态成为processor,大选一个新的leader,事件处理完情形产生follower;没有须要线程的上下文切换

    一、设计格局的归类

    外观形式

    主题理想:在外观类内完毕具体的操作,客商只供给和外观类打交道,屏蔽措施调用细节。

    图片 5外观形式

    5、原型形式(prototype)

    1.以指标为原型,对其进展复制、克隆发生多少个近似的新对象;
    2.简单的能够达成Cloneable 接口;
    3.只要急需深复制,必要选拔流的款型读取二进制,再写入到对应的新目的;

    二、设计方式

    结缘方式

    核心思想:让具体类和这么些类的器皿达成同贰个接口,客户调用到容器类时使用递归调用,无需区分那五头的区分。

    图片 6结合方式

    12、享元情势(Flyweight)

    1.享元形式重要指标是落到实处指标的分享,即分享池,比方数据库连接池;
    2.习认为常与工厂格局一齐利用;

    9、代理格局

    代办形式正是多二个代理类出来,替原对象开展局地操作。代理类仿佛中介,它比大家精通着更加多的音讯。
    演示代码:

    实体接口:
    public interface Sourceable {
        public void method();
    }
    实体类:
    public class Source implements Sourceable {
    
        @Override
        public void method() {
            System.out.println("the original method!");
        }
    }
    代理类:
    public class Proxy implements Sourceable {
    
        private Source source;
    
        public Proxy() {
            super();
            this.source = new Source();
        }
    
        @Override
        public void method() {
            before();
            source.method();
            atfer();
        }
    
        private void atfer() {
            System.out.println("after proxy!");
        }
    
        private void before() {
            System.out.println("before proxy!");
        }
    }
    测试代码:
    public class ProxyTest {
    
        public static void main(String[] args) {
            Sourceable source = new Proxy();
            source.method();
        }
    }
    

    一言以蔽之工厂方式

    大旨情想:将类的始建进度与对象的选用进程分别。

    图片 7大致工厂形式

    具体贯彻进程:定义一个厂子,依照参数的例外重回不一样类的实例。因为大家希望将工厂生产的指标足以选取同样的诀要管理,所以产品类类常常会兑现均等的接口。

    10、桥接形式(Bridge)

    1.桥接方式把事情和其具体的落成分开,以便他们能够分级独立的变迁;
    2.概念三个接口A,接口能够有八个完毕类;
    3.概念三个抽象类,抽象类持有A的落到实处,提供获取、设置A完成类的格局;
    4.具体的桥接类,完成抽象类,并开首化接口A的实例类设置给桥接类中调用该实例的主意;

    3、单例情势

    单例对象(Singleton)是一种常用的设计格局。在Java应用中,单例对象能担保在二个JVM中,该目的唯有三个实例存在。
    演示代码:

    单例类:
    public class Singleton {  
    
        /* 持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载 */  
        private static Singleton instance = null;  
    
        /* 私有构造方法,防止被实例化 */  
        private Singleton() {  
        }  
    
        /* 静态工程方法,创建实例 */  
        public static Singleton getInstance() {  
            if (instance == null) {  
                instance = new Singleton();  
            }  
            return instance;  
        }  
    
        /* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */  
        public Object readResolve() {  
            return instance;  
        }  
    }   
    
    这个类可以满足基本要求,但是,像这样毫无线程安全保护的类,
    如果我们把它放入多线程的环境下,肯定就会出现问题了,
    如何解决?我们首先会想到对getInstance方法加synchronized关键字,
    如下:
    public static synchronized Singleton getInstance() {  
            if (instance == null) {  
                instance = new Singleton();  
            }  
            return instance;  
        }  
    
    但是,synchronized关键字锁住的是这个对象,这样的用法,
    在性能上会有所下降,因为每次调用getInstance(),都要对对象上锁,
    事实上,只有在第一次创建对象的时候需要加锁,之后就不需要了,
    所以,这个地方需要改进。我们改成下面这个:
    public static Singleton getInstance() {  
            if (instance == null) {  
                synchronized (instance) {  
                    if (instance == null) {  
                        instance = new Singleton();  
                    }  
                }  
            }  
            return instance;  
        }  
    

    将synchronized关键字加在了里面,也正是说当调用的时候是无需加锁的,独有在instance为null,并创设对象的时候才供给加锁,质量有一定的提拔。
    看上面包车型地铁状态:在Java指令中创造对象和赋值操作是分手举行的,也正是说instance = new Singleton();语句是分两步推行的。可是JVM并不保险那五个操作的前后相继顺序,约等于说有极大或然JVM会为新的Singleton实例分配空间,然后径直赋值给instance成员,然后再去最初化这几个Singleton实例。那样就只怕出错了,大家以A、B多少个线程为例:

    a>A、B线程同期步向了第二个if决断
    b>A首先步入synchronized块,由于instance为null,所以它推行instance = new Singleton();
    c>由于JVM内部的优化学工业机械制,JVM先画出了部分分配给Singleton实例的空白内部存款和储蓄器,并赋值给instance成员(注意此时JVM未有起来起先化这几个实例),然后A离开了synchronized块。
    d>B步向synchronized块,由于instance此时不是null,因此它马上离开了synchronized块并将结果重临给调用该方法的程序。
    e>此时B线程筹算利用Singleton实例,却发现它未有被伊始化,于是错误发生了。

    为此程序照旧有希望发生错误,其实程序在运营进度是很复杂的,从这一点大家就可以见见,特别是在写多线程遭受下的顺序更有难度,有挑衅性。我们对该程序做更加的优化:

    private static class SingletonFactory{           
            private static Singleton instance = new Singleton();           
        }           
        public static Singleton getInstance(){           
            return SingletonFactory.instance;           
        }  
    
    实际情况是,单例模式使用内部类来维护单例的实现,JVM内部的机制
    能够保证当一个类被加载的时候,这个类的加载过程是线程互斥的。这
    样当我们第一次调用getInstance的时候,JVM能够帮我们保证instance
    只被创建一次,并且会保证把赋值给instance的内存初始化完毕,这样
    我们就不用担心上面的问题。同时该方法也只会在第一次调用的时候使
    用互斥机制,这样就解决了低性能问题。这样我们暂时总结一个完美的
    单例模式:
    public class Singleton {  
    
        /* 私有构造方法,防止被实例化 */  
        private Singleton() {  
        }  
    
        /* 此处使用一个内部类来维护单例 */  
        private static class SingletonFactory {  
            private static Singleton instance = new Singleton();  
        }  
    
        /* 获取实例 */  
        public static Singleton getInstance() {  
            return SingletonFactory.instance;  
        }  
    
        /* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */  
        public Object readResolve() {  
            return getInstance();  
        }  
    }  
    
    也有人这样实现:因为我们只需要在创建类的时候进行同步,所以只要将
    创建和getInstance()分开,单独为创建加synchronized关键字,也是可以
    的:
    public class SingletonTest {  
    
        private static SingletonTest instance = null;  
    
        private SingletonTest() {  
        }  
    
        private static synchronized void syncInit() {  
            if (instance == null) {  
                instance = new SingletonTest();  
            }  
        }  
    
        public static SingletonTest getInstance() {  
            if (instance == null) {  
                syncInit();  
            }  
            return instance;  
        }  
    }  
    

    填补:接纳"影子实例"的措施为单例对象的天性同步更新

    public class SingletonTest {  
    
        private static SingletonTest instance = null;  
        private Vector properties = null;  
    
        public Vector getProperties() {  
            return properties;  
        }  
    
        private SingletonTest() {  
        }  
    
        private static synchronized void syncInit() {  
            if (instance == null) {  
                instance = new SingletonTest();  
            }  
        }  
    
        public static SingletonTest getInstance() {  
            if (instance == null) {  
                syncInit();  
            }  
            return instance;  
        }  
    
        public void updateProperties() {  
            SingletonTest shadow = new SingletonTest();  
            properties = shadow.getProperties();  
        }  
    }  
    

    本文由68399皇家赌场发布于集群主机,转载请注明出处:java-23种设计格局(笔记一)

    关键词: 性能 随笔 模式 句话 核心

上一篇:数据结构(集结)

下一篇:没有了