精华内容
下载资源
问答
  • Java常用设计模式总结及应用场景分析

    万次阅读 多人点赞 2019-03-12 16:24:00
    java常用设计模式总结 2017年11月23日 21:30:54 qq_14827935 阅读数:3284 ...

    掌握常用的几种(最起码单例模式、工厂模式),了解其他的设计模式即可,做到手里有粮,心里不慌。首先,掌握每种模式的定义及使用场景。其次,掌握一个形象的例子,简单的过一遍代码。
    学习设计模式的真正目的:编程时,有意识地面向接口编程,多用封装、继承、组合、多态等OOP思想,而不仅仅是死记几类设计模式。

    常用的设计模式分类:
    创建型(创建一个对象):单例模式、工厂模式、抽象工厂模式
    结构型(将几个对象组织成一个结构):桥接模式、外观模式、代理模式
    行为型(多个对象间的通信):观察者模式、策略模式
    其中,工厂模式、桥接模式、策略模式有点像,放在一起理解(几个对象具有共同特征,因此继承共同的接口,然后通过工厂、桥去访问)。另外,工厂模式和外观模式(几个对象间有先后关系,是串行的,而非工厂模式中的并行,因此几个对象组合成一个外观类,通过这个外观类来访问)区别很明显,也因此放在一起理解。

    参考引用:

    http://www.runoob.com/design-pattern/proxy-pattern.html
    https://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.html
    https://www.cnblogs.com/chinajava/p/5880870.html

    设计模式定义

    被反复使用的,代码设计经验的总结。

    设计模式的原则

    总结起来,就是多用接口/抽象类,从而增加代码的可扩展性(减少修改代码)。降低模块间的依赖和联系。
    体现了OOP的模块化、可扩展性等特征。

    工厂模式

    定义与使用场合:现在需要创建几个对象,且这几个对象有共同特征,则不需要具体创建各个对象,而是创建对象工厂类即可。
    一般常用静态工厂模式。
    例子:发送邮件和短信(共同特征:发送的消息)
    这里写图片描述

    public interface Sender {  
        public void Send();  
    }  
    • 1
    • 2
    • 3
    public class MailSender implements Sender {  
        @Override  
        public void Send() {  
            System.out.println("this is mailsender!");  
        }  
    }  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    public class SmsSender implements Sender {  
    
        @Override  
        public void Send() {  
            System.out.println("this is sms sender!");  
        }  
    }  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    public class SendFactory {  
    
        public static Sender produceMail(){  
            return new MailSender();  
        }  
    
        public static Sender produceSms(){  
            return new SmsSender();  
        }  
    }  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    public class FactoryTest {  
    
        public static void main(String[] args) {      
            Sender sender = SendFactory.produceMail();  
            sender.Send();  
        }  
    }  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    抽象工厂模式

    工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则
    定义与使用场景:同上。
    例子:同上。
    这里写图片描述

    public interface Provider {  
        public Sender produce();  
    }  
    • 1
    • 2
    • 3
    public class SendMailFactory implements Provider {  
    
        @Override  
        public Sender produce(){  
            return new MailSender();  
        }  
    }  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    public class SendSmsFactory implements Provider{  
    
        @Override  
        public Sender produce() {  
            return new SmsSender();  
        }  
    }  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    public class Test {  
    
        public static void main(String[] args) {  
            Provider provider = new SendMailFactory();  
            Sender sender = provider.produce();  
            sender.Send();  
        }  
    }  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    总结:如果要新增发送微信,则只需做一个实现类,实现Sender接口,同时做一个工厂类,实现Provider接口,就OK了,无需去改动现成的代码。这样做,拓展性较好!
    所有工厂模式中,抽象工厂模式最先进。

    策略模式及与工厂模式的区别

    定义与使用场合:一个系统需要动态地在几种类似的算法中选择一种。
    与工厂模式异同:实例化一个对象的位置不同。对工厂模式而言,实例化对象是放在了工厂类里面。而策略模式实例化对象的操作在调用的地方。本质都是继承与多态。
    例子: 现有 加/减/乘 几种算法,输入参数返回值都一样(可以理解成类似的算法)。现在需要在调用时动态配置算法策略,实现对不同算法的调用。
    这里写图片描述

    public interface Strategy {
       public int doOperation(int num1, int num2);
    }
    • 1
    • 2
    • 3
    public class OperationAdd implements Strategy{
       @Override
       public int doOperation(int num1, int num2) {
          return num1 + num2;
       }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    public class OperationSubstract implements Strategy{
       @Override
       public int doOperation(int num1, int num2) {
          return num1 - num2;
       }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    public class OperationMultiply implements Strategy{
       @Override
       public int doOperation(int num1, int num2) {
          return num1 * num2;
       }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    public class Context {
       private Strategy strategy;
    
       public Context(Strategy strategy){
          this.strategy = strategy;
       }
    
       public int executeStrategy(int num1, int num2){
          return strategy.doOperation(num1, num2);
       }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    public class StrategyPatternDemo {
       public static void main(String[] args) {
           //实例化对象的位置在调用处
          Context context = new Context(new OperationAdd());        
          System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
    
          context = new Context(new OperationSubstract());        
          System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
    
          context = new Context(new OperationMultiply());        
          System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
       }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    单例模式

    定义及使用场合:只有一个对象被创建。
    例子:
    建议采用 饿汉式 创建方法。线程安全,容易实现。初始化慢一点。

    public class SingleObject {
    
       //创建 SingleObject 的一个对象
       private static SingleObject instance = new SingleObject();
    
       //让构造函数为 private,这样该类就不会被实例化
       private SingleObject(){}
    
       //获取唯一可用的对象
       public static SingleObject getInstance(){
          return instance;
       }
    
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    观察者模式

    定义与使用场景:一个对象(subject)被其他多个对象(observer)所依赖。则当一个对象变化时,发出通知,其它依赖该对象的对象都会收到通知,并且随着变化。
    比如 声音报警器和闪光灯报警器分别订阅热水器温度,热水器温度过高时,发出通知,两个报警器分别发声、闪光以实现报警。
    又比如很多人订阅微信公众号,该公众号有更新文章时,自动通知每个订阅的用户。
    **实现:**1,多个观察者要订阅这个对象 2,这个对象要发出通知

    例子:
    这里写图片描述

    public interface Observer {  
        public void update();  
    }  
    • 1
    • 2
    • 3
    public class Observer1 implements Observer {  
    
        @Override  
        public void update() {  
            System.out.println("observer1 has received!");  
        }  
    }  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    public class Observer2 implements Observer {  
    
        @Override  
        public void update() {  
            System.out.println("observer2 has received!");  
        }  
    
    }  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    public interface Subject {  
    
        /*增加观察者*/  
        public void add(Observer observer);  
    
        /*删除观察者*/  
        public void del(Observer observer);  
    
        /*通知所有的观察者*/  
        public void notifyObservers();  
    
        /*自身的操作*/  
        public void operation();  
    }  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    public abstract class AbstractSubject implements Subject {  
    
        private Vector<Observer> vector = new Vector<Observer>();  
        @Override  
        public void add(Observer observer) {  
            vector.add(observer);  
        }  
    
        @Override  
        public void del(Observer observer) {  
            vector.remove(observer);  
        }  
    
        @Override  
        public void notifyObservers() {  
            Enumeration<Observer> enumo = vector.elements();  
            while(enumo.hasMoreElements()){  
                enumo.nextElement().update();  
            }  
        }  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    public class MySubject extends AbstractSubject {  
    
        @Override  
        public void operation() {  
            System.out.println("update self!");  
            notifyObservers();  
        }  
    
    }  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    public class ObserverTest {  
    
        public static void main(String[] args) {  
            Subject sub = new MySubject();  
            sub.add(new Observer1());  //订阅这个对象
            sub.add(new Observer2());  
    
            sub.operation();  //发出改变的一个通知
        }  
    
    }  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    代理模式

    定义与使用场景:一个代理类代表一个真实类的功能,通过访问代理类来实现对真实类的访问。
    比如买火车票这件小事:黄牛相当于是火车站的代理,我们可以通过黄牛买票,但只能去火车站进行改签和退票。
    又比如需要对原有的方法进行修改,就是采用一个代理类调用原有的方法,以避免修改原有代码。
    例子:
    这里写图片描述
    一个真实对象realSubject提供一个代理对象proxy。通过proxy可以调用realSubject的部分功能*,并添加一些额外的业务处理*,同时可以屏蔽realSubject中未开放的接口。
    1、RealSubject 是委托类,Proxy 是代理类;
    2、Subject 是委托类和代理类的接口;
    3、request() 是委托类和代理类的共同方法;

    interface Subject {
        void request();
    }
    
    class RealSubject implements Subject {
        public void request(){
            System.out.println("RealSubject");
        }
    }
    
    class Proxy implements Subject {
        private Subject subject;
    
        public Proxy(Subject subject){
            this.subject = subject;
        }
        public void request(){
            System.out.println("begin");
            subject.request();
            System.out.println("end");
        }
    }
    
    public class ProxyTest {
        public static void main(String args[]) {
            RealSubject subject = new RealSubject();
            Proxy p = new Proxy(subject);
            p.request();
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    桥接模式及与策略模式的区别

    定义与使用场景:访问多种数据库驱动(多个具有共同特征的数据库驱动),不是直接访问,而是通过DriverManager桥来访问。

    这里写图片描述
    例子: 不再具体实现了。
    这里写图片描述
    与策略模式的区别:(个人觉得较复杂,了解即可。本质都是面向接口编程,体现继承与多态)
    策略模式:我要画圆,要实心圆,我可以用solidPen来配置,画虚线圆可以用dashedPen来配置。这是strategy模式。
    桥接模式:同样是画圆,我是在windows下来画实心圆,就用windowPen+solidPen来配置,在unix下画实心圆就用unixPen+solidPen来配置。如果要再windows下画虚线圆,就用windowsPen+dashedPen来配置,要在unix下画虚线圆,就用unixPen+dashedPen来配置。
    所以相对策略模式,桥接模式要表达的内容要更多,结构也更加复杂。

    外观模式

    定义与使用场景:见例子。又比如,去医院看病,可能要去挂号、门诊、划价、取药,让患者或患者家属觉得很复杂,如果有提供接待人员,只让接待人员来处理,就很方便。
    例子:计算机启动,需要先启动CPU,再启动memory,最后启动disk。这三个类之间具有先后关系(依赖关系)。
    这里写图片描述
    与工厂模式的区别:工程模式多个类具有共同特征(继承一个共同的接口),是并列的。而外观模式多个类是有先后关系,是串行的,用组合。

    贴部分代码:

    public class Computer {  
    //是组合,而非继承。这是与工程模式的显著区别。
        private CPU cpu;  
        private Memory memory;  
        private Disk disk;  
    
        public Computer(){  
            cpu = new CPU();  
            memory = new Memory();  
            disk = new Disk();  
        }  
    
        public void startup(){  
            System.out.println("start the computer!");  
            cpu.startup();  
            memory.startup();  
            disk.startup();  
            System.out.println("start computer finished!");  
        }  
    
        public void shutdown(){  
            System.out.println("begin to close the computer!");  
            cpu.shutdown();  
            memory.shutdown();  
            disk.shutdown();  
            System.out.println("computer closed!");  
        }  
    }  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    public class User {  
    
        public static void main(String[] args) {  
            Computer computer = new Computer();  
            //将计算机的启动过程封装成一个类
            computer.startup();  
            computer.shutdown();  
        }  
    }  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    生产者-消费者模式

    定义与使用场景:生产者把数据放入缓冲区,而消费者从缓冲区取出数据。
    例子:缓冲区一般为队列(FIFO),但在生产消费较为频繁时,队列push,pop内存消耗较大,此时可以考虑环形缓冲区(以数组、链表方式实现)。
    通过互斥锁防止缓冲区同时读写。通过信号量控制缓冲区大小(满的时候不允许写,空的时候不允许读)


    作者:qq_14827935
    来源:CSDN
    原文:https://blog.csdn.net/qq_14827935/article/details/78618652

    展开全文
  • 工厂模式工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过...
    工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
    介绍
    意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
    主要解决:主要解决接口选择的问题。
    何时使用:我们明确地计划不同条件下创建不同实例时。
    如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品。
    关键代码:创建过程在其子类执行。
    应用实例: 1、您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。 2、Hibernate 换数据库只需换方言和驱动就可以。
    优点: 1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口。
    缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
    使用场景: 1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。 2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。 3、设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。
    注意事项:作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。
    实现
    我们将创建一个 Shape 接口和实现 Shape 接口的实体类。下一步是定义工厂类 ShapeFactory。

    FactoryPatternDemo,我们的演示类使用 ShapeFactory 来获取 Shape 对象。它将向 ShapeFactory 传递信息(CIRCLE / RECTANGLE / SQUARE),以便获取它所需对象的类型。


    工厂模式的 UML 图

    步骤 1:创建一个接口

    Shape.java


    步骤 2:创建实现接口的实体类

    Rectangle.java


    Square.java

    Circle.java

    步骤 3:创建一个工厂,生成基于给定信息的实体类的对象
    ShapeFactory.java


    步骤 4:使用该工厂,通过传递类型信息来获取实体类的对象
    FactoryPatternDemo.java


    步骤 5:
    验证输出


    展开全文
  • 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象...
    单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
    这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

    注意:1、单例类只能有一个实例;2、单例类必须自己创建自己的唯一实例;3、单例类必须给所有其他对象提供这一实例。
    介绍
    意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
    主要解决:一个全局使用的类频繁地创建与销毁。
    何时使用:当您想控制实例数目,节省系统资源的时候。
    如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
    关键代码:构造函数是私有的。
    应用实例: 1、一个党只能有一个主席。 2、Windows 是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象,所以所有文件的处理必须通过唯一的实例来进行。 3、一些设备管理器常常设计为单例模式,比如一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件。
    优点: 1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。 2、避免对资源的多重占用(比如写文件操作)。
    缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
    使用场景: 1、要求生产唯一序列号。 2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。 3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。
    注意事项:getInstance() 方法中需要使用同步锁 synchronized (Singleton.class) 防止多线程同时进入造成 instance 被多次实例化。
    实现

    我们将创建一个 SingleObject 类。SingleObject 类有它的私有构造函数和本身的一个静态实例。SingleObject 类提供了一个静态方法,供外界获取它的静态实例。SingletonPatternDemo,我们的演示类使用 SingleObject 类来获取 SingleObject 对象。


    单例模式的 UML 图
    步骤 1:创建一个 Singleton 类。
    SingleObject.java


    步骤 2:从 singleton 类获取唯一的对象。
    SingletonPatternDemo.java


    步骤 3:验证输出。

    单例模式的几种实现方式
    1、懒汉式,线程不安全
    是否 Lazy 初始化
    是否多线程安全
    实现难度:
    描述:这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。这种方式 lazy loading 很明显,不要求线程安全,在多线程不能正常工作。

    代码实例:


    接下来介绍的几种实现方式都支持多线程,但是在性能上有所差异。
    2、懒汉式,线程安全
    是否 Lazy 初始化:
    是否多线程安全:

    实现难度:
    描述:这种方式具备很好的 lazy loading,能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步。
    优点:第一次调用才初始化,避免内存浪费。
    缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。getInstance() 的性能对应用程序不是很关键(该方法使用不太频繁)。
    代码实例:

    3、饿汉式
    是否 Lazy 初始化:
    是否多线程安全:

    实现难度:
    描述:这种方式比较常用,但容易产生垃圾对象。
    优点:没有加锁,执行效率会提高。
    缺点:类加载时就初始化,浪费内存。
    它基于 classloder 机制避免了多线程的同步问题,不过,instance 在类装载时就实例化,虽然导致类装载的原因有很多种,在单例模式中大多数都是调用 getInstance 方法, 但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化 instance 显然没有达到 lazy loading 的效果。
    代码实例:

    4、双检锁/双重校验锁(DCL,即 double-checked locking)
    JDK 版本:JDK1.5 起
    是否 Lazy 初始化:
    是否多线程安全:

    实现难度:较复杂
    描述:这种方式采用双锁机制,安全且在多线程情况下能保持高性能。getInstance() 的性能对应用程序很关键。
    代码实例:

    5、登记式/静态内部类
    是否 Lazy 初始化:
    是否多线程安全:

    实现难度:一般
    描述:这种方式能达到双检锁方式一样的功效,但实现更简单。对静态域使用延迟初始化,应使用这种方式而不是双检锁方式。这种方式只适用于静态域的情况,双检锁方式可在实例域需要延迟初始化时使用。这种方式同样利用了 classloder 机制来保证初始化 instance 时只有一个线程,它跟第 3 种方式不同的是:第 3 种方式只要 Singleton 类被装载了,那么 instance 就会被实例化(没有达到 lazy loading 效果),而这种方式是 Singleton 类被装载了,instance 不一定被初始化。因为 SingletonHolder 类没有被主动使用,只有通过显式调用 getInstance 方法时,才会显式装载 SingletonHolder 类,从而实例化 instance。想象一下,如果实例化 instance 很消耗资源,所以想让它延迟加载,另外一方面,又不希望在 Singleton 类加载时就实例化,因为不能确保 Singleton 类还可能在其他的地方被主动使用从而被加载,那么这个时候实例化 instance 显然是不合适的。这个时候,这种方式相比第 3 种方式就显得很合理。
    代码实例:

    6、枚举
    JDK 版本:JDK1.5 起
    是否 Lazy 初始化:
    是否多线程安全:

    实现难度:
    描述:这种实现方式还没有被广泛采用,但这是实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化。这种方式是 Effective Java 作者 Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。不过,由于 JDK1.5 之后才加入 enum 特性,用这种方式写不免让人感觉生疏,在实际工作中,也很少用。不能通过 reflection attack 来调用私有构造方法。
    代码实例:

    经验之谈:一般情况下,不建议使用第 1 种和第 2 种懒汉方式,建议使用第 3 种饿汉方式。只有在要明确实现 lazy loading 效果时,才会使用第 5 种登记方式。如果涉及到反序列化创建对象时,可以尝试使用第 6 种枚举方式。如果有其他特殊的需求,可以考虑使用第 4 种双检锁方式。
    展开全文
  • java设计模式学习汇总

    千次阅读 2017-03-07 10:33:50
    1.什么是设计模式 设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。设计模式使代码编制真正工程化,设计...

    1.什么是设计模式

    设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理地运用设计模式可以完美地解决很多问题,每种模式在现实中都有相应的原理来与之对应,每种模式都描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是设计模式能被广泛应用的原因。
    学习设计模式不能单纯的死磕概念,要结合身边实际例子,进行对比归纳,慢慢体会总结,在工作中多思考,练习,才能熟练掌握,本来设计模式就是一种思路,是为了提高代码质量而不是仅仅是解决业务实现,所以学习也是很有必要的,毕竟每一个程序员都有一个成为万人敬仰大神的心愿(当然路途是漫长的,但是行远自迩,登高自卑,一步一步坚持下去,不忘初心),刚开始学习的时候容易混淆,容易前学后忘,为了提高学习设计模式的效率,在网上有很多同类文章的时候,自己也写博客,记录一下自己的学习,便于加深理解和以后复习,鉴于自己水平离大神还差得很远,不足的地方也不吝赐教,互相学习,共同进步。

    2.设计模式六大原则

    2.1、开闭原则(Open Close Principle)


    开闭原则的意思是:对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。

    2.2、里氏代换原则(Liskov Substitution Principle)


    里氏代换原则是面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。

    2.3、依赖倒转原则(Dependence Inversion Principle)


    这个原则是开闭原则的基础,具体内容:针对接口编程,依赖于抽象而不依赖于具体。

    2.4、接口隔离原则(Interface Segregation Principle)


    这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。它还有另外一个意思是:降低类之间的耦合度。由此可见,其实设计模式就是从大型软件架构出发、便于升级和维护的软件设计思想,它强调降低依赖,降低耦合。

    2.5、迪米特法则,又称最少知道原则(Demeter Principle)


    最少知道原则是指:一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。

    2.6、合成复用原则(Composite Reuse Principle)


    合成复用原则是指:尽量使用合成/聚合的方式,而不是使用继承。

    3.设计模式分类

    总共有 23 种设计模式。这些模式可以分为三大类:
    创建型模式(Creational Patterns)、结构型模式(Structural Patterns)、行为型模式(Behavioral Patterns)。

    3.1 创建型模式

    共五种:

    工厂方法模式、抽象工厂模式、

    单例模式

    建造者模式、原型模式。

    3.2 结构型模式

    共七种:

    适配器模式装饰着模式代理模式

    外观模式、桥接模式、组合模式、享元模式。

    3.3 行为型模式

    共十一种:

    策略模式 、 模板方法模式、观察者模式

    迭代子模式、责任链模式、命令模式、

    备忘录模式、状态模式、访问者模式、

    中介者模式、解释器模式。


    抽象层次越高,接口的语意就越模糊,适用的范围就越广,在著名的《设计模式》一书中,其实在反复强调一点: 发现变化并且封装变化,针对接口编程而不是实现编程。 很多人看书是只关注具体的模式,而忽略了模式的本质目的。

         今后将一一总结每个设计模式的使用,开始先从常用的设计模式(学习过的在对应设计模式上面会有链接跳转)开始,虽然网上也有不少文章,但是别人的东西始终是别人的,只有自己的才是自己的,同时也在此立文督促自己!

    展开全文
  • Java设计模式学习09——装饰模式

    千次阅读 2016-11-03 19:11:02
    一、定义装饰(Decorate)模式又称为包装(Wrapper)模式。装饰模式是以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。二、职责 动态的为一个对象增加新的功能。 装饰模式是一种用于代替继承的技术,...
  • 这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。 这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调用。 介绍 意图:为子系统中的一...
  • 这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入...
  • 这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高...
  • 这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。我们将通过创建 5 个对象来画出 20 个分布于...
  • 设计模式(Design pattern) 它代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一...
  • 这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。介绍意图:提供一个...
  • 这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。...
  • 过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。这种类型的设计模式属于结构型模式,它...
  • 这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。介绍意图:将一个复杂的构建与其表示相分离,使得同样的构建过程...
  • 这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。我们通过下面的实例来演示装饰器模式的用法。...
  • java常用设计模式应用案例

    万次阅读 2012-10-12 16:15:08
    设计模式; 一个程序员对设计模式的理解: “不懂”为什么要把很简单的东西搞得那么复杂。后来随着软件开发经验的增加才开始明白我所看到的“复杂”恰恰就是设计模式的精髓所在,我所理解的“简单”就是一把钥匙开...
  • 这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。我们通过下面的实例来演示组合模式的用法。实例演示了一个组织中员工的层次...
  • Java设计模式——单例设计模式

    千次阅读 2018-05-25 10:13:31
    我们一般在学习的第一个设计模式都是单例设计模式,因为单例设计模式广泛的应用在我们程序开发中。今天就和大家简单的聊一聊单例设计模式,因为在我们刚开始学习Java基础时,就了解了单例,有的同学在学习时非常困惑...
  • Java设计模式PDF中文版

    千次下载 热门讨论 2009-11-11 11:00:03
    PDF中文版Java设计模式 Java 提供了丰富的API,同时又有强大的数据库系统作底层支持,那么我们的编程似乎 变成了类似积木的简单"拼凑"和调用,甚至有人提倡"蓝领程序员",这些都是对现代编 程技术的不了解所至. 在...
  • JAVA学习33_Java 设计模式面试题

    千次阅读 2016-09-11 10:51:27
    第 1 页 共 10 页 ...MVC 设计模式应用观察者模式的框架模式) M: Model(Business process layer) ,模型,操作数据的业务处理层 , 并独立于表现层 (Independe nt of presentation) 。 V:
  • 今天开始,我们LazyCoder准备着手开发一款模拟人生游戏,首先从设计人物开始,我们设想我们设计的人物可以讲话,吃东西,睡觉,他们的样子也都不一样。我们想到了继承,于是有了第一个类Person,之后我们再设计各种...
  • 代理模式(Proxy)其实每个模式名称就表明了该模式的作用,代理模式就是多一个代理类出来,替原对象进行一些操作,比如我们在租房子的时候回去找中介,为什么呢?因为你对该地区房屋的信息掌握的不够全面,希望找一...
  • java设计模式

    千次阅读 2012-04-04 16:09:50
    Java设计模式 分类: java学习 2011-09-04 20:48 883人阅读 评论(6) 收藏 举报 设计模式公司荣誉出品 您的设计模式 我们的设计模式 CBF4LIFE 2009 年5 月 我希望这本书的阅读者具备最基本的代码编写能力,...
  • Java 语言I/O库的设计中,使用了两个结构模式,即装饰模式和适配器模式。本篇围绕这两个模式讨论Java I/O库的设计
  • 学习Java设计模式的10条建议

    千次阅读 2014-07-28 15:11:13
    设计模式在整个Java学习路线图中有着承上启下的作用。
  • Java设计模式之起始

    千次阅读 2014-03-11 10:42:52
    摘要:本系列笔记记录了学习设计模式的一些学习过程和所获、不会记录全部四人组的23种设计模式应用驱动学习、主要记录了常用的一些设计模式设计模式没有对与错、大胆设计、细心求证、切勿设计过头!
  • Java设计模式:23种设计模式全面解析

    千次阅读 多人点赞 2020-01-18 08:20:52
    一、什么是设计模式 设计模式是一套被反复使用、多数人知晓的、经过分类编写的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。毫无疑问,设计模式使代码编程真正...
  • JAVA设计模式--享元模式

    万次阅读 多人点赞 2016-10-09 22:07:09
    二、享元模式Java中的典型应用 三、享元模式的结构 单纯享元模式 复合享元模式 四、享元模式应用举例 五、享元模式的适用性 六、享元模式的特点 七、总结 一、什么是享元模式 享元Flyweight模式是构造型...
  • Java设计模式及实践

    千次阅读 2019-12-01 17:00:06
    Java设计模式及实践读后感 1 简介  这本书是在程序员节日20月24那天晚上在海友酒店,写完Git如何保留两地并行开发的提交之后购买的,由于编写博客时坐姿不对,第二天肋骨酸疼,持续了好几天,尴尬。在北京整个联试...
  • Java设计模式之简单工厂模式

    千次阅读 2016-04-25 17:33:21
    Java设计模式之简单工厂模式近来在学习Java的设计模式,一直觉得设计模式很难,所以一直没有去接触,一则是工作比较忙没有闲工夫去学习,二来是因为自己比较懒所以也懒得动,幸亏今天在公司还挺闲的,所以找了一本书...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 230,516
精华内容 92,206
关键字:

java设计模式学习及应用

java 订阅