6大设计原则&23种设计模式

1、设计模式六大原则

1.1、单一职责

一个类只负责一项职责,应该仅有一个引起它变化的原因。

优点:

  • 可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多;
  • 提高类的可读性,提高系统的可维护性;
  • 变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响。

1.2、里氏替换原则

子类可以扩展父类的功能,但不能改变父类原有的功能。即任何基类可以出现的地方,子类一定可以出现,并且当用子类替换了基类后程序不受影响。

含义:

  • 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
  • 子类中可以增加自己特有的方法。
  • 当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。【注意区分重载和重写】
  • 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

1.3、依赖倒置原则

要求对抽象进行编程,不要对实现进行编程。

实际编程中需要做到:

  • 低层模块尽量都要有抽象类或接口,或者两者都有。【可能会被人用到的】
  • 变量的声明类型尽量是抽象类或接口。
  • 使用继承时遵循里氏替换原则。

1.4、接口隔离原则

建立单一接口,不要建立庞大臃肿的接口,尽量细化接口,接口中的方法尽量少。

注意:

  • 接口尽量小,但是要有限度。对接口进行细化可以提高程序设计灵活性是不挣的事实,但是如果过小,则会造成接口数量过多,使设计复杂化。所以一定要适度。
  • 为依赖接口的类定制服务,只暴露给调用的类它需要的方法,它不需要的方法则隐藏起来。只有专注地为一个模块提供定制服务,才能建立最小的依赖关系。
  • 提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。

1.5、迪米特法则(最少知道原则)

一个对象应该对其他对象保持最少的了解。迪米特法则其根本思想,是强调了类之间的松耦合。

1.6、开闭原则

一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。

2、23种设计模式

2.1、设计模式的三种分类

img

  • 创建型模式:对象实例化的模式,创建型模式用于解耦对象的实例化过程。
  • 结构型模式:把类或对象结合在一起形成一个更大的结构。
  • 行为型模式:类和对象如何交互,及划分责任和算法。

2.2、模式特点

  • 单例模式:某个类只能有一个实例,提供一个全局的访问点。

    • 饿汉式—静态常量方式(线程安全):

      public class Singleton {  
          private static Singleton instance = new Singleton();  
          private Singleton (){}  
          public static Singleton getInstance() {  
          	return instance;  
          }  
      }
      

      类加载时就初始化实例,避免了多线程同步问题。天然线程安全。

    • 饿汉式—静态代码块方式(线程安全):

      public class Singleton {
          private static Singleton instance;
          static {
              instance = new Singleton();
          }
          private Singleton() {}
          public static Singleton getInstance() {
              return instance;
          }
      }
      

      其实就是在上面 静态常量饿汉式 实现上稍微变动了一下,将类的实例化放在了静态代码块中而已。其他没区别。

    • 懒汉式(线程不安全):

      public class Singleton {
          private static Singleton singleton;
          private Singleton() {}
          public static Singleton getInstance() {
              if (singleton == null) {
                  singleton = new Singleton();
              }
              return singleton;
          }
      }
      

      这是最基本的实现方式,第一次调用才初始化,实现了懒加载的特性。多线程场景下禁止使用,因为可能会产生多个对象,不再是单例。

    • 懒汉式(线程安全,方法上加同步锁):

      public class Singleton {
          private static Singleton singleton;
          private Singleton() {}
          public static synchronized Singleton getInstance() {
              if (singleton == null) {
                  singleton = new Singleton();
              }
              return singleton;
          }
      }
      

      和上面 懒汉式(线程不安全)实现上唯一不同是:获取实例的getInstance()方法上加了同步锁。保证了多线程场景下的单例。但是效率会有所折损,不过还好。

    • 双重校验锁(线程安全,效率高):

      public class Singleton {
      	private volatile static Singleton singleton;
      	private Singleton() {}
      	public static Singleton getSingleton() {
      		if (singleton == null) {
      			synchronized (Singleton.class) {
      				if (singleton == null) {
      					singleton = new Singleton();
      				}
      			}
      		}
      		return singleton;
      	}
      }
      

      此种实现中不用每次需要获得锁,减少了获取锁和等待的事件。
      注意volatile关键字的使用,保证了各线程对singleton静态实例域修改的可见性。

    • 静态内部类实现单例(线程安全、效率高):

      public class Singleton {  
          private static class SingletonHolder {
          	private static final Singleton INSTANCE = new Singleton();
          }
          private Singleton (){}
          public static final Singleton getInstance() {
          	return SingletonHolder.INSTANCE;
          }
      }
      

      这种方式下 Singleton 类被装载了,instance 不一定被初始化。因为 SingletonHolder 类没有被主动使用,只有通过显式调用 getInstance 方法时,才会显式装载 SingletonHolder 类,从而实例化 instance。
      注意内部类SingletonHolder要用static修饰且其中的静态变量INSTANCE必须是final的。

  • 简单工厂:一个工厂类根据传入的参量决定创建出那一种产品类的实例。

  • 工厂方法:定义一个创建对象的接口,让子类决定实例化那个类。

  • 抽象工厂:创建相关或依赖对象的家族,而无需明确指定具体类。

  • 建造者模式:封装一个复杂对象的构建过程,并可以按步骤构造。

  • 原型模式:通过复制现有的实例来创建新的实例。

  • 适配器模式:将一个类的方法接口转换成客户希望的另外一个接口。

  • 组合模式:将对象组合成树形结构以表示“”部分-整体“”的层次结构。

  • 装饰模式:动态的给对象添加新的功能。

  • 代理模式:为其他对象提供一个代理以便控制这个对象的访问。

  • 亨元(蝇量)模式:通过共享技术来有效的支持大量细粒度的对象。

  • 外观模式:对外提供一个统一的方法,来访问子系统中的一群接口。

  • 桥接模式:将抽象部分和它的实现部分分离,使它们都可以独立的变化。

  • 模板模式:定义一个算法结构,而将一些步骤延迟到子类实现。

  • 解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器。

  • 策略模式:定义一系列算法,把他们封装起来,并且使它们可以相互替换。

  • 状态模式:允许一个对象在其对象内部状态改变时改变它的行为。

  • 观察者模式:对象间的一对多的依赖关系。

  • 备忘录模式:在不破坏封装的前提下,保持对象的内部状态。

  • 中介者模式:用一个中介对象来封装一系列的对象交互。

  • 命令模式:将命令请求封装为一个对象,使得可以用不同的请求来进行参数化。

  • 访问者模式:在不改变数据结构的前提下,增加作用于一组对象元素的新功能。

  • 责任链模式:将请求的发送者和接收者解耦,使的多个对象都有处理这个请求的机会。

  • 迭代器模式:一种遍历访问聚合对象中各个元素的方法,不暴露该对象的内部结构。

posted @   是老胡啊  阅读(301)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
点击右上角即可分享
微信分享提示