软件开发者使用的。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员在相当长的一段时间内反复试验的结果。设计模式分为23种经典模式,按用途可分为三类。这些是创建模式、结构模式和行为模式。创建模式:创建模式提供了一种在创建对象时隐藏创建逻辑的方法,而不是直接使用new运算符实例化对象。这允许程序更灵活地确定需要为给定实例创建哪些对象。结构模式:结构模式旨在通过改变代码结构来达到解耦的目的,使我们的代码易于维护和扩展。行为模式:行为模式侧重于各个类之间的交互,明确划分职责,让我们的代码更加清晰。设计模式的六大原则1.开闭原则(OpenClosePrinciple)开闭原则的意思是:对扩展开放,对修改关闭。当程序需要扩展时,不能修改原有代码,达到热插拔的效果。简而言之,就是让程序具有可扩展性,易于维护和升级。实现这个效果需要用到接口和抽象类,后面具体设计的时候会提到。2.里氏代换原则(LiskovSubstitutionPrinciple)里氏代换原则是面向对象设计的基本原则之一。根据里氏替换原则,基类可以出现的地方,子类就一定会出现。LSP是继承重用的基石。只有派生类能够替代基类,软件单元的功能不受影响时,基类才能真正重用,派生类也可以在基类的基础上增加新的。行为。Liskov替换原则是对开闭原则的补充。实现开闭原则的关键步骤是抽象,而基类和子类之间的继承关系就是抽象的具体实现,所以里氏代换原则就是具体实现抽象步骤的规范。3.依赖倒置原则(DependenceInversionPrinciple)这个原则是开闭原则的基础。具体内容:接口编程,要靠抽象,不能靠具体。4.接口隔离原则(InterfaceSegregationPrinciple)这个原则的意思是:使用多个隔离的接口优于使用单个接口。它还有另外一个意思:降低类之间的耦合度。可见,设计模式实际上是一种从大型软件架构出发,易于升级和维护的软件设计思想。它强调减少依赖和耦合。5.得墨忒耳定律,又称最少已知原则(DemeterPrinciple)最少已知原则是指一个实体应尽可能少地与其他实体进行交互,使系统功能模块相对独立。6.复合复用原则(CompositeReusePrinciple)复合复用原则是指:尽量使用合成/聚合而不是继承。常用设计模式要掌握1.工厂模式(FactoryPattern)基本概念工厂模式(FactoryPattern)是最常用的设计模式之一。这种类型的设计模式是一种创建模式,它提供了一种创建对象的最佳方式。在工厂模式下,我们在创建对象时不向客户端暴露创建逻辑,而是使用一个通用的接口指向新创建的对象。意图:定义一个创建对象的接口,让其子类决定实例化哪个工厂类,工厂模式将创建过程延迟到子类。主要解决:主要解决接口选择问题。何时使用:当我们明确计划在不同条件下创建不同的实例时。解决方法:让其子类实现工厂接口,并返回一个抽象产品。代码示例}}publicclassCircleFactoryimplementsShape{@Overridepublicvoiddraw(){System.out.println("使用简单工厂模式创建一个圆圈");}}publicstaticvoidmain(String[]args){Shapeshape=newCircleFactory();shape.draw();}2.SingletonPattern基本概念SingletonPattern是Java中最简单的设计模式之一。这种类型的设计模式是一种创建模式,它提供了一种创建对象的最佳方式。此模式涉及一个类,该类负责创建自己的对象,同时确保只创建一个对象。此类提供了一种直接访问其唯一对象的方法,而无需实例化此类的对象。单例模式的特点:一个单例类只能有一个实例。单例类必须创建自己的唯一实例。单例类必须将此实例提供给所有其他对象。意图:确保一个类只有一个实例并为其提供一个全局访问点。主要解决方案:一个全局使用的类被频繁创建和销毁。何时使用:当你想控制实例数量和节省系统资源时。解决方法:判断系统是否已经有这个单例,有则返回,没有则创建。代码示例//必须掌握的单例模式的编写/***Lazy非线程安全*/publicstaticclassLazyNosafe{privatestaticLazyNosafelazyNosafe;publicstaticLazyNosafegetLazyNosafe(){lazyNosafe=newLazyNosafe();返回lazyNosafe;}}/***惰性线程安全*/publicstaticclassLazySafe{privatestaticLazySafelazySafe;同步公共静态LazySafegetLazyNosafe(){lazySafe=newLazySafe();返回懒惰安全;}}/***饥饿模式*/publicstaticclassHungerSingle{privatestaticHungerSinglehungerSingle=newHungerSingle();publicstaticHungerSinglegetHungerSingle(){返回hungerSingle;}}/***HungerSingle变体*/publicstaticotherclassHungerSingleOther{privatestaticHungerSingleSingleOtherhunger=hunger;statnewHungerSingleOther();}publicstaticHungerSingleOthergetHungerSingleOther(){返回hungerSingleOther;}}/***DCL双重检查*/publicstaticclassDclSingleton{private静态DclSingletondclSingleton;publicstaticDclSingletongetDclSingleton(){if(dclSingleton!=null){synchronized(dclSingleton){if(dclSingleton!=null){dclSingleton=newDclSingleton();}}}返回dclSingle/*;}}**DCLdoublecheck,optimizedversion*/publicstaticclassDclSingletonOther{//禁止通过volatile进行指令重排,保证顺序加载privatestaticvolatileDclSingletondclSingleton;publicstaticDclSingletongetDclSingleton(){if(dclSingleton!=null){synchronized(dclSingleton){if(dclSingleton!=null){dclSingleton=newDclSingleton();}}}返回dclSingleton;}}/***静态内部类*使用classloader机制保证初始化实例时只有一个线程*/publicstaticclassStaticClassSingleton{privatestaticclassStaticSingleton{publicstaticfinalStaticSingletonstaticS单例=newStaticSingleton();}publicstaticStaticSingletongetStaticSingleton(){返回StaticSingleton.staticSingleton;}}/***枚举方法*/publicenumEnumSingleton{INSTANCE;}3.代理模式(ProxyPattern)基本概念代理在代理模式中,一个类代表另一个类的功能。这种类型的设计模式是一种结构模式。在代理模式中,我们使用现有对象创建对象,以便为外界提供功能接口。意图:为其他对象提供代理以控制对此对象的访问。主要解决:直接访问对象带来的问题,例如:要访问的对象在远程机器上。在面向对象的系统中,由于某些原因(比如对象创建成本很高,或者某些操作需要安全控制,或者需要进程外访问),直接访问会给用户或系统结构带来很多麻烦。我们可以在访问这个对象的时候给这个对象加上一个访问层。何时使用:想要对类的访问进行一些控制。解决方法:增加中间层。代码示例publicinterfaceCat{voidsayMiao();voidrun();}publicclassBlackCatimplementsCat{@OverridepublicvoidsayMiao(){System.out.println("黑喵");}@Overridepublicvoidrun(){System.out.println("Blackrun");}}publicclassPoxyCatimplementsCat{privateBlackCatblackCat=newBlackCat();@OverridepublicvoidsayMiao(){//在待办事项之前blackCat.sayMiao();//在todo之后}@Overridepublicvoidrun(){//在todo之前blackCat.run();//Aftertodo}}4.适配器模式(AdapterPattern)基本概念适配器模式(AdapterPattern)是作为两个不兼容接口之间的桥梁。这种类型的设计模式是一种结构模式,结合了两个独立界面的功能。此模式涉及负责加入独立或不兼容的接口功能的单个类。举一个真实的例子,读卡器作为存储卡和笔记本之间的适配器。你把内存卡插入读卡器,再把读卡器插入笔记本,这样笔记本就可以读取内存卡了。意图:将一个类的接口转换为客户想要的另一个接口。Adapter模式使那些由于接口不兼容而无法一起工作的类能够一起工作。主要解决方案:主要解决方案是在一个软件系统中,往往需要将一些“已有的对象”放到一个新的环境中,而新环境所需要的接口是已有的对象无法满足的。何时使用:1、系统需要使用已有的类,而这样的接口不满足系统的需要。2.我想创建一个可重用的类来与一些彼此关系不大的类一起工作,包括一些将来可能会引入的类。这些源类不一定具有一致的接口。3.通过接口转换将一个类插入到另一个类系统中。(比如老虎和鸟,现在有一只飞虎,在不增加实体要求的情况下,增加一个适配器,里面有一个老虎对象,实现飞翔的接口。)如何解决:继承或依赖(推荐).代码示例publicinterfaceCat{voidsayMiao();voidrun();}publicclassanimalsAdapterimplementsCat{@OverridepublicvoidsayMiao(){}@Overridepublicvoidrun(){}}publicclassDogextendsanimalsAdapter{@Overridepublicvoidrun(){System.out.println(“狗跑”);}}5.FacadePattern基本概念FacadePattern隐藏了系统的复杂性,提供了一个客户端可以访问系统的接口。这类设计模式是一种结构模式,它在现有系统上增加一个接口,以隐藏系统的复杂性。此模式涉及单个类,该类为客户端请求提供简化方法并委托对现有系统类方法的调用。意图:为子系统中的一组接口提供一致的接口。外观模式定义了一个高级接口,使子系统更易于使用。主要解决方案:降低复杂系统内部子系统的访问复杂度,简化客户端之间的接口。什么时候使用:1.客户端不需要知道系统内部的复杂连接,整个系统只需要提供一个“接待员”。2.定义系统入口。如何解决:客户端没有和系统耦合,外观类和系统耦合。代码示例}}publicclassRectangleimplementsShape{@Overridepublicvoiddraw(){System.out.println("Rectangle::draw()");}}publicclassShapeMaker{privateShapecircle;私有形状矩形;publicShapeMaker(){circle=newCircle();矩形=新矩形();}publicvoiddrawCircle(){circle.draw();}publicvoiddrawRentangle(){rectangle.draw();模式),类的行为或其算法可以在运行时改变。这种类型的设计模式是一种行为模式。在策略模式中,我们创建代表各种策略的对象和一个上下文对象,其行为随着策略对象的变化而变化。策略对象更改上下文对象的执行算法。意图:定义一系列算法,将它们一个一个封装起来,使它们可以互换。主要解决方案:在多个相似算法的情况下,使用if...else复杂且难以维护。何时使用:一个系统有很多很多类,区分它们的是它们的直接行为。解决方法:将这些算法一一封装成类,任意替换。代码范例战略;publicStrategyContext(策略策略){this.strategy=strategy;}publicvoiddraw(){strategy.draw();}}7.TemplatePattern的基本概念在TemplatePattern中,一个抽象类公开定义方法/模板来实现它的方法。它的子类可以根据需要覆盖方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式是一种行为模式。意图:在操作中定义算法的框架,同时将一些步骤推迟到子类。模板方法允许子类在不改变算法结构的情况下重新定义算法的某些特定步骤。主要解决:有些方法是通用的,但是在每个子类中都重写了这个方法。何时使用:有一些通用方法。如何解决:抽象这些常见的算法。代码示例publicabstractclassAbstractTemplate{publicvoidexecute(){init();做一点事();结尾();}publicvoidinit(){System.out.println("初始化");}publicvoiddosomething(){}publicvoidend(){System.out.println("结束执行");}}publicclassDemoTemplateextendsAbstractTemplate{@Overridepublicvoiddosomething(){System.out.println("自定义方法");}}publicstaticvoidmain(String[]args){AbstractTemplateabstractTemplate=newDemoTemplate();abstractTemplate.execute();}8.观察者模式的基本概念当对象之间存在一对多关系时,观察观察者模式。例如,当一个对象被修改时,它的依赖对象会被自动通知。观察者模式是一种行为模式。意图:定义对象之间一对多的依赖关系。当一个对象的状态发生变化时,所有依赖它的对象都会自动得到通知和更新。主要解决:一个对象状态改变通知其他对象的问题,兼顾易用性和低耦合性,保证高度协作。何时使用:当一个对象(目标对象)的状态发生变化时,所有的依赖对象(观察者对象)都会收到通知并广播通知。如何解决:使用面向对象技术,可以弱化这种依赖。代码示例publicclassSubjects{privateList
