作业二

| 这个作业属于哪个课程 | <班级的链接> |

| ----------------- |--------------- |

| 这个作业要求在哪里| <作业要求的链接> |

| 这个作业的目标 | <理解软件设计原则、设计模式> |

参考资料

参考书籍

《Head First 设计模式》

参考视频

Java设计模式详解

正文

归纳总结

七大原则

单一职责原则SRP

  • 修改一个类的原因只有一个,换句话说就是让一个类只负责一件事,当这个类需要做过多事情的时候,就需要分解这个类
  • 如果一个类承担的职责过多,就等于把这些职责耦合在了一起,一个职责的变化可能会削弱这个类完成其它职责的能力

接口隔离原则ISP

  • 不应该强迫客户端依赖于它们不用的方法
  • 因此使用多个专门的接口比使用单一的总接口要好

依赖倒转原则DIP

  • 高层模块不应该依赖于低层模块,二者都应该依赖于抽象
  • 抽象不应该依赖于细节,细节应该依赖于抽象
  • 高层模块包含一个应用程序中重要的策略选择和业务模块,如果高层模块依赖于低层模块,那么低层模块的改动就会直接影响到高层模块,从而迫使高层模块也需要改动
  • 依赖于抽象意味着
    • 任何变量都不应该持有一个指向具体类的指针或者引用
    • 任何类都不应该从具体类派生
    • 任何方法都不应该覆写它的任何基类中的已经实现的方法

里式替换原则LSP

  • 子类对象必须能够替换掉所有父类对象
  • 继承是一种 IS-A 关系,子类需要能够当成父类来使用,并且需要比父类更特殊
  • 如果不满足这个原则,那么各个子类的行为上就会有很大差异,增加继承体系的复杂度

开闭原则OCP

  • 类应该对扩展开放,对修改关闭
  • 扩展就是添加新功能的意思,因此该原则要求在添加新功能时不需要修改代码
  • 符合开闭原则最典型的设计模式是装饰者模式,它可以动态地将责任附加到对象上,而不用去修改类的代码

迪米特法则LOD

  • 一个对象应该对其他对象保持最少的了解
  • 迪米特法则又叫最少知道原则,即一个类对自己依赖的类知道的越少越好
  • 也就是说,对于被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部
  • 对外除了提供的public 方法,不对外泄露任何信息

合成复用原则

  • 尽量使用合成/聚合的方式,而不是使用继承

设计模式

创建型模式

  • 简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

  • 工厂方法模式(Factory Method Pattern):又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式,它属于类创建型模式。在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。

  • 抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。

  • 建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。建造者模式属于对象创建型模式。根据中文翻译的不同,建造者模式又可以称为生成器模式。

  • 单例模式(Singleton Pattern):单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。单例模式的要点有三个:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。单例模式是一种对象创建型模式。单例模式又名单件模式或单态模式。

结构型模式

  • 适配器模式(Adapter Pattern):将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。

  • 桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。

  • 装饰模式(Decorator Pattern)::动态地给一个对象增加一些额外的职责(Responsibility),就增加对象功能来说,装饰模式比生成子类实现更为灵活。其别名也可以称为包装器(Wrapper),与适配器模式的别名相同,但它们适用于不同的场合。根据翻译的不同,装饰模式也有人称之为“油漆工模式”,它是一种对象结构型模式。

  • 外观模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。外观模式又称为门面模式,它是一种对象结构型模式。

  • 享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式,它是一种对象结构型模式。

  • 代理模式(Proxy Pattern):给某一个对象提供一个代理,并由代理对象控制对原对象的引用。代理模式的英 文叫做Proxy或Surrogate,它是一种对象结构型模式。

行为型模式

  • 命令模式(Command Pattern):将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。命令模式是一种对象行为型模式,其别名为动作(Action)模式或事务(Transaction)模式。

  • 中介者模式(Mediator Pattern)定义:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式又称为调停者模式,它是一种对象行为型模式。

  • 观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。

  • 状态模式(State Pattern):允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。其别名为状态对象(Objects for States),状态模式是一种对象行为型模式。

  • 策略模式(Strategy Pattern):定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化,也称为政策模式(Policy)。

心得体会

  • 在使用Java进行开发的过程中,设计模式无处不在。但很多人可能没有意识到这一点,那是因为很多设计模式都封装在了底层,而我们如果没有进行深度研究,就不会发现设计模式非常有用且无处不在。

  • 下面是我在日常开发中发现的一些应用到设计模式的例子

  • 单例模式

    • java.lang.Runtime采用了饿汉式单例
    // 饿汉式单例
    public class Runtime {
        private static Runtime currentRuntime = new Runtime();
    
        /**
         * Returns the runtime object associated with the current Java application.
         * Most of the methods of class <code>Runtime</code> are instance
         * methods and must be invoked with respect to the current runtime object.
         *
         * @return  the <code>Runtime</code> object associated with the current
         *          Java application.
         */
        public static Runtime getRuntime() {
            return currentRuntime;
        }
    
        /** Don't let anyone else instantiate this class */
        private Runtime() {}
    }
    
    
    • spring IOC使用了单例bean

    • 当然我们有时会遇到自己实现单例模式的情况

    • 单例模式其实也有很多种不同的实现方式,这里给出我自己实现的单例模式

    • 饿汉式

    public class Singleton{
    	// 类内部实例化
    	private final static Singleton instance = new Singleton();
    	// 构造器私有化,防止new对象
    	private Singleton(){
    	
    	}
    	// 对外提供公有方法调用
    	public static Singleton getInstance(){
    		return instance;
    	}
    	
    	// 反序列化保证单例
    	pubile Object readResolve(){
    		return instance;
    	}
    }
    
    • 懒汉式
    public class Singleton{
    	// 使用 volatile 防止 指令重排序
        private static volatile Singleton instance;
        //构造器私有化,防止new对象
        private Singleton() {
        
        }
        //只有在第一次使用的时候构造实例对象,使用synchronized代码块和双重判断避免多线程问题,并且提供效率
        public static Singleton getInstance() {
            if (instance == null){
                synchronized (Singleton.class){
                    if (instance == null){
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
    
  • 享元模式

    // Integer 等包装类使用了 享元模式
    public final class Integer extends Number implements Comparable<Integer> {
        public static Integer valueOf(int i) {
            if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
            return new Integer(i);
        }
    
        private static class IntegerCache {
            static final int low = -128;
            static final int high;
            static final Integer cache[];
    
            static {
                // high value may be configured by property
                int h = 127;
                String integerCacheHighPropValue =
                    sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
                if (integerCacheHighPropValue != null) {
                    try {
                        int i = parseInt(integerCacheHighPropValue);
                        i = Math.max(i, 127);
                        // Maximum array size is Integer.MAX_VALUE
                        h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                    } catch( NumberFormatException nfe) {
                        // If the property cannot be parsed into an int, ignore it.
                    }
                }
                high = h;
    
                cache = new Integer[(high - low) + 1];
                int j = low;
                for(int k = 0; k < cache.length; k++)
                    cache[k] = new Integer(j++);
    
                // range [-128, 127] must be interned (JLS7 5.1.7)
                assert IntegerCache.high >= 127;
            }
    
            private IntegerCache() {}
        }
    }
    
  • 工厂模式

    • spring 采用 简单工厂模式 + 配置文件的方式
  • 策略模式

    • 线程池的拒绝策略
  • 模板方法模式

    • 利用抽象类中的非抽象方法
    • AQS
    • 自定义类加载器的实现
      • 继承ClassLoader类,并重写findClass方法
    • spring中的jdbc Template(模板方法 + 回调模式)
  • 迭代器模式

    • 使用迭代器模式时,只需要自定义容器类实现java.util.Iterable并实现其中的iterator()方法使其返回一个java.util.Iterator的实现类即可
  • 观察者模式

    • 通过java.util.Observable类和 java.util.Observer接口定义了观察者模式,只要实现它们的子类就可以编写观察者模式实例
  • 适配器模式

    • SpringMVC中的HandlerAdapter使用了适配器模式
  • 代理模式

    • JDK动态代理
    • Spring AOP的实现

相关截图

posted @ 2022-03-05 13:51  淋煮柒  阅读(35)  评论(0)    收藏  举报