精华内容
下载资源
问答
  • 常用的设计模式面试题
    千次阅读
    2022-06-06 21:37:31

    1、说说项目中使用过的设计模式

    设计模式是经过高度抽象化的在编程中可以被反复使用的代码设计经验的总结,项目中常见的有单列模式,建设者模式,策略模式,模板方法模式,外观模式

    1、单列模式:单列模式是保证系统唯一性的重要的手段,单列模式首先通过把类的构造器私有化来防止程序通过其它的方式创建该类的实列,然后通过提供一个全局的唯一方法来帮助用户来获得该类的实例,用户只需要也只能通过调用该方法获得该类实列

    常见的方法:1、懒汉模式 2、饿汉模式 3、双重校验锁 4 静态内部类等实现方式

    应用常见:应用程序的日志应用、创建数据库连接池、多线程的线程池等

    2、建造者(Builder)模式的定义:将组件和组件的组装过程分开,然后⼀步⼀步建造⼀个复杂的对象,在项目中常用来创建实体类,

    • 在要构造的类内部创建一个静态对象类builder;、
    • 静态内部类的参数和构建类一致;
    • 直接调用建造者对应的方法,为对应的属性赋值
    • 最后只要调用建造者提供的build方法即可根据我们的配置返回一个对象

    3、模板方法:提供了一个抽象类,将部分逻辑以具体的方法的形式实现,然后声名一些抽象的方法来迫使子类实现的逻辑,不同的子类可以通过的不同的方式实现这些抽象的方法,从而实现不同的业务逻辑

    4、外观模式

    提供一个统一的接口,用来访问子系统中的一群接口,外观定义了一个高层的接口,让子系统使用更加容易

    5、策略模式为同一个行为定义了不同的策略,并为每种策略都实现了不同的方法.使用策略模式可以避免使用多重条件if…else if…else语句,

    策略模式的主要角色如下

    抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
    具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。
    环境(Context)类:持有一个策略类的引用,环境角色使用抽象策略(Strategy)类接口调用不同的算法,最终给客户端调用。

    6、工厂模式:工厂模式在接口中定义了创建对象的方法,而将具体的创建对象的过程在子类中实现,用户只需通过接口创建需要的对象即可,不用关注对象的具体创建过程。同时,不同的子类可根据需求灵活实现创建对象的不同方法

    7、原型模式:原型(Prototype)模式的定义:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象

    原型模式的克隆分为浅克隆和深克隆。

    浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址

    深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

    8、适配器模式(Adapter)的定义如下:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。适配器模式分为类结构型模式、对象结构型模式和接口适配器模式

    适配器模式(Adapter)包含以下主要角色。

    目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。
    适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。
    适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。

    9、装饰器模式:不改变原来代码和继承关系的情况下,动态的扩张类的功能,如框架controller文件提供before和after方法

    装饰者模式包括source(被装饰类)和decorator(装饰类)

    10、迭代器模式

    提供了一个方法顺序访问一个聚合对象中各个元素,又不需要暴露该对象的内部表示

    11、代理模式

    代理模式指为对象提供一种通过代理的方式访问并控制该对象行为的方法,通过代理控制对象的访问,可以再这个对象调用方法之前去处理、添加新功能

    12、桥接模式

    桥接模式通过将抽象及其实现解耦,使得两者可以根据需求独立变化,通过定义一个抽象和实现之前的桥接  者来达到解耦的目的

    桥接模式主要用于解决需求多变的情况下使用继承造成爆炸的问题,扩展起来不够灵活

    13、组合模式

    主要用于实现部分和整体操作的一致性,组合模式常根据树型结构表示部分及整体的关系

    14、享元模式

    主要通过对象的复用来减少对象的创建的次数和数量,减少系统内存的使用和减低系统的负载

    15、观察者模式

    观察者模式指被观察者的状态发生变化时,系统基于时间驱动理论将其状态通知到订阅其状态的观察者中,用以完成状态的修改和事件的传播

    16、责任链模式

    为了避免请求发送者与多个请求处理者耦合在一起,责任链模式让所有的请求处理者持有下一个对象的引用,从而将请求串联成一条链,在有请求发生的时候,可以将请求沿着这条链传递,直到遇到该对象的处理器

    更多相关内容
  • php中设计模式非常多,但是设计模式在php面试题经常会提到,本文主要给大家介绍php经典面试题设计模式,需要的朋友一起看看吧
  • Java设计模式面试题及答案 下载链接:全部面试题及答案PDF 1.请列举出在 JDK 中几个常用的设计模式? 单例模式(Singleton pattern)用于 Runtime,Calendar 和其他的一些类中。工厂模式 (Factory pattern)被用于...

    Java面试题及答案(2022版),每道都是认真筛选出的高频面试题,助力大家能找到满意的工作!

    Java设计模式面试题及答案

    下载链接全部面试题及答案PDF

    1.请列举出在 JDK 中几个常用的设计模式?

    单例模式(Singleton pattern)用于 Runtime,Calendar 和其他的一些类中。工厂模式
    (Factory pattern)被用于各种不可变的类如 Boolean,像 Boolean.valueOf,观察者模式
    (Observer pattern)被用于 Swing 和很多的事件监听中。装饰器设计模式(Decorator
    design pattern)被用于多个 Java IO 类中。

    2.什么是设计模式?你是否在你的代码里面使用过任何设计模式?

    设计模式是世界上各种各样程序员用来解决特定设计问题的尝试和测试的方法。设计模式是代码可用性的延伸

    3.Java 中什么叫单例设计模式?请用 Java 写出线程安全的单例模式

    单例模式重点在于在整个系统上共享一些创建时较耗资源的对象。整个应用中只维护一个特定类实例,它被所有组件共同使用。Java.lang.Runtime 是单例模式的经典例子。从 Java5 开始你可以使用枚举(enum)来实现线程安全的单例。

    4.在 Java 中,什么叫观察者设计模式(observer design pattern)?

    观察者模式是基于对象的状态变化和观察者的通讯,以便他们作出相应的操作。简单的例子就是一个天气系统,当天气变化时必须在展示给公众的视图中进行反映。这个视图对象是一个主体,而不同的视图是观察者。

    5.使用工厂模式最主要的好处是什么?在哪里使用?

    工厂模式的最大好处是增加了创建对象时的封装层次。如果你使用工厂来创建对象,之后你可以使用更高级和更高性能的实现来替换原始的产品实现或类,这不需要在调用层做任何修改。

    6.举一个用 Java 实现的装饰模式(decorator design pattern)?它是作用于对象层次还是类层次?

    装饰模式增加强了单个对象的能力。Java IO 到处都使用了装饰模式,典型例子就是Buffered 系列类如 BufferedReader 和 BufferedWriter,它们增强了 Reader 和 Writer 对象,以实现提升性能的 Buffer 层次的读取和写入。

    7.在 Java 中,为什么不允许从静态方法中访问非静态变量?

    Java 中不能从静态上下文访问非静态数据只是因为非静态变量是跟具体的对象实例关联的,而静态的却没有和任何实例关联。

    8.设计一个 ATM 机,请说出你的设计思路?

    比如设计金融系统来说,必须知道它们应该在任何情况下都能够正常工作。不管是断电还是其他情况,ATM 应该保持正确的状态(事务) , 想想 加锁(locking)、事务(transaction)、错误条件(error condition)、边界条件(boundary condition) 等等。尽管你不能想到具体的设计,但如果你可以指出非功能性需求,提出一些问题,想到关于边界条件,这些都会是很好的。

    9.在 Java 中,什么时候用重载,什么时候用重写?

    如果你看到一个类的不同实现有着不同的方式来做同一件事,那么就应该用重写(overriding),而重载(overloading)是用不同的输入做同一件事。在 Java 中,重载的方法签名不同,而重写并不是。

    10.举例说明什么情况下会更倾向于使用抽象类而不是接口?

    接口和抽象类都遵循”面向接口而不是实现编码”设计原则,它可以增加代码的灵活性,可以适应不断变化的需求。下面有几个点可以帮助你回答这个问题:在 Java 中,你只能继承一个类,但可以实现多个接口。所以一旦你继承了一个类,你就失去了继承其他类的机会了。

    接口通常被用来表示附属描述或行为如:Runnable、Clonable、Serializable 等等,因此当你
    使用抽象类来表示行为时,你的类就不能同时是 Runnable 和 Clonable(注:这里的意思是指如果把 Runnable 等实现为抽象类的情况),因为在 Java 中你不能继承两个类,但当你使用接口时,你的类就可以同时拥有多个不同的行为。

    在一些对时间要求比较高的应用中,倾向于使用抽象类,它会比接

    口稍快一点。如果希望把一系列行为都规范在类继承层次内,并且可以更好地在同一个地方进行编码,那么抽象类是一个更好的选择。有时,接口和抽象类可以一起使用,接口中定义函数,而在抽象类中定义默认的实现。

    11. ⼯⼚⽅法模式(利⽤创建同⼀接⼝的不同实例)

    1、普通⼯⼚模式:建⽴⼀个⼯⼚类,对实现了同⼀接⼝的⼀些类进⾏实例的创建;

    12.接口是什么?为什么要使用接口而不是直接使用具体类?

    接口用于定义 API。它定义了类必须得遵循的规则。同时,它提供了一种抽象,因为客户端只使用接口,这样可以有多重实现,如 List 接口,你可以使用可随机访问的 ArrayList,也可以使用方便插入和删除的 LinkedList。接口中不允许写代码,以此来保证抽象,但是 Java 8 中你可以在接口声明静态的默认方法,这种方法是具体的。

    13.java中,抽象类与接口之间有什么区别?

    1.一个类可以实现多个接口 ,但却只能继承最多一个抽象类。

    2.抽象类可以包含具体的方法 , 接口的所有方法都是抽象的。

    3.抽象类可以声明和使用字段 ,接口则不能,但接口可以创建静态的final常量。

    4.接口的方法都是public的,抽象类的方法可以是public,protected,private或者默认的package;

    5.抽象类可以定义构造函数,接口却不能。

    14.除了单例模式,你在生产环境中还用过什么设计模式?

    这需要根据你的经验来回答。一般情况下,你可以说依赖注入,工厂模式,装饰模式或者观察者模式,随意选择你使用过的一种即可。不过你要准备回答接下的基于你选择的模式的问题。

    15.什么是里氏替换原则?

    1、开闭原则(Open Close Principle)

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

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

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

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

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

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

    这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。所以上文中多次出现:降低依赖,降低耦合。

    5、迪米特法则(最少知道原则)(Demeter Principle)

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

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

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

    16.什么情况下会违反迪米特法则?为什么会有这个问题?

    迪米特法则建议“只和朋友说话,不要陌生人说话”,以此来减少类之间的耦合。

    17.适配器模式是什么?什么时候使用?

    18.适配器模式与装饰器模式有什么区别?

    19.适配器模式和代理模式之间有什么不同?

    20.什么是模板方法模式?

    21.什么时候使用访问者模式?

    22.什么时候使用组合模式?

    23.继承和组合之间有什么不同?

    24.描述Java中的重载与重写?什么时候用重载,什么时候用重写?

    25.Java中,嵌套公共静态类与顶级类有什么不同?

    26.OOP中的组合、聚合和关联有什么区别?

    27.给我一个符合开闭原则的设计模式的例子?

    28.使用工厂模式最主要的好处是什么?你在哪里使用?

    29.工厂模式与抽象工厂模式的区别?

    30.什么是设计模式?你是否在你的代码里面使用过任何设计模式?

    31.你可以说出几个在JDK库中使用的设计模式吗?

    32.Java中什么是单例设计模式?用Java写出线程安全的单例

    33.什么是责任链设计模式?

    下载链接博主已将以上这些面试题整理成了一个面试手册,是PDF版的

    展开全文
  • Java常见设计模式面试题及答案

    万次阅读 2021-03-29 06:12:47
    2. JDK 中常用设计模式有哪些?3.单例模式是什么?请用 Java 写出线程安全的单例模式4.在 Java 中,什么叫观察者模式(observer design pattern)?5.使用工厂模式有哪些好处?说说它的应用场景?6.举一个 Java中 ...


    前    言
    本文仅收录了一些常见的设计模式面试题,如需查看其它java面试题可查看我另一篇博文:

    JAVA | 2021最全Java面试题及答案汇总


    正    文

    1.设计模式是什么?你是否在代码中使用过?

    设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。

    设计模式就是程序员总结出来的一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。,

    2. JDK 中常用的设计模式有哪些?

    在这里插入图片描述

    3.单例模式是什么?请用 Java 写出线程安全的单例模式

    单例(Singleton)模式:指一个类只有一个实例,且该类能自行创建这个实例的一种模式。Java.lang.Runtime 是单例模式的经典例子。

    public class Singleton5 {
        private Singleton5(){}
        private static class InstanceHolder{
            private static Singleton5 instance = new Singleton5();
        }
        public static Singleton5 getInstance(){
            return InstanceHolder.instance;
        }
    }
    

    就是套了一个私有的静态内部类。java语言规范保证了,一个类或者接口的静态成员在被赋值的时候,这个类会初始化(有个初始化锁,每个线程都会至少获取一次初始化锁保证初始化),这个过程比较复杂,结果就是对任意线程,内部可以重排序,但是这种重排序对其他线程不可见。这个也是Google推荐的写法。

    4.在 Java 中,什么叫观察者模式(observer design pattern)?

    观察者(Observer)模式 指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式,它是对象行为型模式。

    观察者模式是一种对象行为型模式,其主要优点如下:

    • 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。符合依赖倒置原则。
    • 目标与观察者之间建立了一套触发机制。

    它的主要缺点如下:

    • 目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用。
    • 当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。

    5.使用工厂模式有哪些好处?说说它的应用场景?

    工厂模式包括简单工厂模式工厂方法模式抽象工厂模式三种。

    在这里插入图片描述

    6.举一个 Java中 实现装饰模式的例子?

    在这里插入图片描述

    7.在 Java 中,什么时候用重载,什么时候用重写?

    在这里插入图片描述

    8. Java 是否可以从静态方法中访问非静态变量?为什么?

    在这里插入图片描述

    9.什么情况下更倾向于使用抽象类而非接口?

    接口和抽象类都遵循”面向接口而不是实现编码”设计原则,它可以增加代码的灵活性,可以适应不断变化的需求。下面有几个点可以帮助你回答这个问题:

    在 Java 中,你只能继承一个类,但可以实现多个接口。所以一旦你继承了一个类,你就失去了继承其他类的机会了。
    接口通常被用来表示附属描述或行为如:Runnable、Clonable、Serializable
    等等,因此当你使用抽象类来表示行为时,你的类就不能同时是 Runnable 和 Clonable(注:这里的意思是指如果把 Runnable
    等实现为抽象类的情况),因为在 Java 中你不能继承两个类,但当你使用接口时,你的类就可以同时拥有多个不同的行为。

    • 在一些对时间要求比较高的应用中,倾向于使用抽象类,它会比接口稍快一点。
    • 如果希望把一系列行为都规范在类继承层次内,并且可以更好地在同一个地方进行编码,那么抽象类是一个更好的选择。

    有时,接口和抽象类可以一起使用,接口中定义函数,而在抽象类中定义默认的实现


    干货推荐

    Java设计模式:23种设计模式全面解析(超级详细)
    java中的7种单例模式

    展开全文
  • 设计模式面试题(总结最全面的面试题!!!).docx
  • JAVA常见设计模式面试题

    千次阅读 2021-01-29 09:27:29
    java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例、饿汉式单例、双重检查锁定 1.单例模式有以下特点:  a、单例类只能有一个实例。  b、单例类必须自己创建自己的唯一...

    一、单例模式
    java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例、饿汉式单例、双重检查锁定
    1.单例模式有以下特点
      a、单例类只能有一个实例。
      b、单例类必须自己创建自己的唯一实例。
      c、单例类必须给所有其他对象提供这一实例。
    2.代码特点
      a、私有静态变量
      b、私有构造方法
      c、公有的静态访问方法  
    3.懒汉式

    public class Singleton {
        private Singleton() {}
        private static Singleton single=null;
        //静态工厂方法 
        public static Singleton getInstance() {
             if (single == null) {  
                 single = new Singleton();
             }  
            return single;
        }
    }
    

    懒汉式非线程安全

    4.饿汉式

    	//饿汉式单例类.在类初始化时,已经自行实例化 
    	public class Singleton1 {
    	    private Singleton1() {}
    	    private static final Singleton1 single = new Singleton1();
    	    //静态工厂方法 
    	    public static Singleton1 getInstance() {
    	        return single;
    	    }
    	}
    

    饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的。

    5.懒汉式和饿汉式区别
    在这里插入图片描述
    6.双重检查锁定

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

    7.应用场景

    a、需要频繁创建的一些类,使用单例可以降低系统的内存压力,减少 GC。
    a、某类只要求生成一个对象的时候,如一个班中的班长等。
    b、某些类创建实例时占用资源较多,或实例化耗时较长,且经常使用。
    c、某类需要频繁实例化,而创建的对象又频繁被销毁的时候,如多线程的线程池、网络连接池等。
    e、频繁访问数据库或文件的对象。

    二、工厂模式
    工厂模式是 Java 中最常用的设计模式之一,工厂模式模式的写法有好几种,这里主要介绍三种:简单工厂模式、工厂模式、抽象工厂模式
    1.简单工厂模式
    这里以制造coffee的例子开始工厂模式设计之旅。

    我们知道coffee只是一种泛举,在点购咖啡时需要指定具体的咖啡种类:美式咖啡、卡布奇诺、拿铁等等。

    /**
     * 
     * 拿铁、美式咖啡、卡布奇诺等均为咖啡家族的一种产品
     * 咖啡则作为一种抽象概念
     * @author Lsj
     *
     */
    public abstract class Coffee {
    
        /**
         * 获取coffee名称
         * @return
         */
        public abstract String getName();
        
    }
    
    
    /**
     * 美式咖啡
     * @author Lsj
     *
     */
    public class Americano extends Coffee {
    
        @Override
        public String getName() {
            return "美式咖啡";
        }
    
    }
    
    
    /**
     * 卡布奇诺
     * @author Lsj
     *
     */
    public class Cappuccino extends Coffee {
    
        @Override
        public String getName() {
            return "卡布奇诺";
        }
    
    }
    
    
    /**
     * 拿铁
     * @author Lsj
     *
     */
    public class Latte extends Coffee {
    
        @Override
        public String getName() {
            return "拿铁";
        }
    
    }
    

    2.工厂模式
    定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个,工厂方法让类把实例化推迟到了子类。

    /**
     * 定义一个抽象的咖啡工厂
     * @author Lsj
     */
    public abstract class CoffeeFactory {
        
        /**
         * 生产可制造的咖啡
         * @return
         */
        public abstract Coffee[] createCoffee();
    
    }
    
    
    /**
     * 中国咖啡工厂
     * @author Lsj
     *
     */
    public class ChinaCoffeeFactory extends CoffeeFactory {
    
        @Override
        public Coffee[] createCoffee() {
            // TODO Auto-generated method stub
            return new Coffee[]{new Cappuccino(), new Latte()};
        }
    
    }
    
    
    /**
     * 美国咖啡工厂
     * @author Lsj
     *
     */
    public class AmericaCoffeeFactory extends CoffeeFactory {
    
        @Override
        public Coffee[] createCoffee() {
            // TODO Auto-generated method stub
            return new Coffee[]{new Americano(), new Latte()};
        }
    
    }
    
    
    /**
     * 工厂方法测试
     * @author Lsj
     *
     */
    public class FactoryMethodTest {
    
        static void print(Coffee[] c){
            for (Coffee coffee : c) {
                System.out.println(coffee.getName());
            }
        }
        
        public static void main(String[] args) {
            CoffeeFactory chinaCoffeeFactory = new ChinaCoffeeFactory();
            Coffee[] chinaCoffees = chinaCoffeeFactory.createCoffee();
            System.out.println("中国咖啡工厂可以生产的咖啡有:");
            print(chinaCoffees);
            CoffeeFactory americaCoffeeFactory = new AmericaCoffeeFactory();
            Coffee[] americaCoffees = americaCoffeeFactory.createCoffee();
            System.out.println("美国咖啡工厂可以生产的咖啡有:");
            print(americaCoffees);
        }
    }
    

    3.抽象工厂
    提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

    在上述的场景上继续延伸:咖啡工厂做大做强,引入了新的饮品种类:茶、 碳酸饮料。中国工厂只能制造咖啡和茶,美国工厂只能制造咖啡和碳酸饮料。

    如果用上述工厂方法方式,除去对应的产品实体类还需要新增2个抽象工厂(茶制造工厂、碳酸饮料制造工厂),4个具体工厂实现。随着产品的增多,会导致类爆炸。

    所以这里引出一个概念产品家族,在此例子中,不同的饮品就组成我们的饮品家族, 饮品家族开始承担创建者的责任,负责制造不同的产品。

    /**
     * 抽象的饮料产品家族制造工厂
     * @author Lsj
     *
     */
    public interface AbstractDrinksFactory {
    
        /**
         * 制造咖啡
         * @return
         */
        Coffee createCoffee();
        
        /**
         * 制造茶
         * @return
         */
        Tea createTea();
        
        /**
         * 制造碳酸饮料
         * @return
         */
        Sodas createSodas();
    }
    
    
    /**
     * 中国饮品工厂
     * 制造咖啡与茶
     * @author Lsj
     *
     */
    public class ChinaDrinksFactory implements AbstractDrinksFactory {
    
        @Override
        public Coffee createCoffee() {
            // TODO Auto-generated method stub
            return new Latte();
        }
    
        @Override
        public Tea createTea() {
            // TODO Auto-generated method stub
            return new MilkTea();
        }
    
        @Override
        public Sodas createSodas() {
            // TODO Auto-generated method stub
            return null;
        }
    
    }
    
    
    /**
     * 美国饮品制造工厂
     * 制造咖啡和碳酸饮料
     * @author Lsj
     *
     */
    public class AmericaDrinksFactory implements AbstractDrinksFactory {
    
        @Override
        public Coffee createCoffee() {
            // TODO Auto-generated method stub
            return new Latte();
        }
    
        @Override
        public Tea createTea() {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public Sodas createSodas() {
            // TODO Auto-generated method stub
            return new CocaCola();
        }
    
    }
    
    
    /**
     * 抽象工厂测试类
     * @author Lsj
     *
     */
    public class AbstractFactoryTest {
        
        static void print(Drink drink){
            if(drink == null){
                System.out.println("产品:--" );
            }else{
                System.out.println("产品:" + drink.getName());
            }
        }
        
        public static void main(String[] args) {
            AbstractDrinksFactory chinaDrinksFactory = new ChinaDrinksFactory();
            Coffee coffee = chinaDrinksFactory.createCoffee();
            Tea tea = chinaDrinksFactory.createTea();
            Sodas sodas = chinaDrinksFactory.createSodas();
            System.out.println("中国饮品工厂有如下产品:");
            print(coffee);
            print(tea);
            print(sodas);
            
            AbstractDrinksFactory americaDrinksFactory = new AmericaDrinksFactory();
            coffee = americaDrinksFactory.createCoffee();
            tea = americaDrinksFactory.createTea();
            sodas = americaDrinksFactory.createSodas();
            System.out.println("美国饮品工厂有如下产品:");
            print(coffee);
            print(tea);
            print(sodas);
        }
    
    }
    

    4.总结

    a、简单工厂:不能算是真正意义上的设计模式,但可以将客户程序从具体类解耦。

    b、工厂方法:使用继承,把对象的创建委托给子类,由子类来实现创建方法,可以看作是抽象工厂模式中只有单一产品的情况。

    c、抽象工厂:使对象的创建被实现在工厂接口所暴露出来的方法中。

    工厂模式可以帮助我们针对抽象/接口编程,而不是针对具体类编程,在不同的场景下按具体情况来使用。

    转载自:https://www.cnblogs.com/carryjack/p/7709861.html

    三、代理模式
    代理模式:即通过代理对象访问目标对象,实现目标对象的方法。这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,实现对目标功能的扩展。

    这涉及到一个编程思想:不要随意去修改别人已经写好的代码或者方法(有坑)。如果需要修改,可以通过代理模式实现。

    代理模式通常有三种实现写法:静态代理、动态代理、Cglib代理

    代理模式的UML图
    在这里插入图片描述

    从UML图中,可以看出代理类与真正实现的类都是继承了抽象的主题类,这样的好处在于代理类可以与实际的类有相同的方法,可以保证客户端使用的透明性。
    1.静态代理

    我们先看针对上面UML实现的例子,再看静态代理的特点。
    Subject接口的实现

    public interface Subject {
        void visit();
    }
    

    实现了Subject接口的两个类:

    public class RealSubject implements Subject {
    
        private String name = "byhieg";
        @Override
        public void visit() {
            System.out.println(name);
        }
    }
    public class ProxySubject implements Subject{
    
        private Subject subject;
    
        public ProxySubject(Subject subject) {
            this.subject = subject;
        }
    
        @Override
        public void visit() {
            subject.visit();
        }
    }
    

    具体的调用如下:

    public class Client {
    
        public static void main(String[] args) {
            ProxySubject subject = new ProxySubject(new RealSubject());
            subject.visit();
        }
    }
    

    通过上面的代理代码,我们可以看出代理模式的特点,代理类接受一个Subject接口的对象,任何实现该接口的对象,都可以通过代理类进行代理,增加了通用性。但是也有缺点,每一个代理类都必须实现一遍委托类(也就是realsubject)的接口,如果接口增加方法,则代理类也必须跟着修改。其次,代理类每一个接口对象对应一个委托对象,如果委托对象非常多,则静态代理类就非常臃肿,难以胜任。
    2.动态代理
    动态代理有别于静态代理,是根据代理的对象,动态创建代理类。这样,就可以避免静态代理中代理类接口过多的问题。动态代理是实现方式,是通过反射来实现的,借助Java自带的java.lang.reflect.Proxy,通过固定的规则生成。
    其步骤如下:

    编写一个委托类的接口,即静态代理的(Subject接口)
    实现一个真正的委托类,即静态代理的(RealSubject类)
    创建一个动态代理类,实现InvocationHandler接口,并重写该invoke方法
    在测试类中,生成动态代理的对象。
    第一二步骤,和静态代理一样,不过说了。第三步,代码如下:

    public class DynamicProxy implements InvocationHandler {
        private Object object;
        public DynamicProxy(Object object) {
            this.object = object;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object result = method.invoke(object, args);
            return result;
        }
    }
    

    第四步,创建动态代理的对象

    Subject realSubject = new RealSubject();
    DynamicProxy proxy = new DynamicProxy(realSubject);
    ClassLoader classLoader = realSubject.getClass().getClassLoader();
    Subject subject = (Subject) Proxy.newProxyInstance(classLoader, new  Class[]{Subject.class}, proxy);
    subject.visit();
    

    创建动态代理的对象,需要借助Proxy.newProxyInstance。该方法的三个参数分别是:

    ClassLoader loader表示当前使用到的appClassloader。
    Class<?>[] interfaces表示目标对象实现的一组接口。
    InvocationHandler h表示当前的InvocationHandler实现实例对象。
    

    jdk自带动态代理
    java.lang.reflect.Proxy

    -作用:动态生成代理类和对象

    java.lang.reflect.InvocationHandler(处理器接口)

    - 可以通过invoke方法实现对真实角色的代理访问

    - 每次通过Proxy生成代理类对象时,都指定对对应的处理器对象

    3.Cglib代理

    要实现Cglib代理,必须引入cglib.jar 包,由于Spring-core包中已经包含了cglib功能,且大部分Java项目均引入了spring 相关jar包,这边使用spring的cglib来讲解。(他俩实现方式都是一样的)

    public class CglibProxy implements MethodInterceptor {
    
        //目标对象
        private Object obj;
        public CglibProxy(Object obj){
            this.obj=obj;
        }
     
        //给目标对象创建一个代理对象
        public Object getProxyInstance(){
            //1.工具类
            Enhancer en = new Enhancer();
            //2.设置父类
            en.setSuperclass(obj.getClass());
            //3.设置回调函数
            en.setCallback(this);
            //4.创建子类(代理对象)
            return en.create();
        }
     
        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            System.out.println("CglibProxy--------->");
            return method.invoke(obj,objects);
        }
    }
    

    说明:可以看出,Cglib代理模式实现不需要目标对象一定实现接口,故目标对象如果没有实现接口,可以使用cglib代理模式。其实Spring的代理模式也是这么实现的。

    展开全文
  • 设计模式面试题(总结最全面的面试题!!!)

    万次阅读 多人点赞 2020-04-11 23:26:21
    文章目录设计模式什么是设计模式为什么要学习设计模式设计模式分类设计模式的六大原则开放封闭原则(Open Close Principle)里氏代换原则(Liskov Substitution Principle)依赖倒转原则(Dependence Inversion ...
  • 【BAT必备】设计模式面试题,【BAT必备】设计模式面试题,【BAT必备】设计模式面试题,【BAT必备】设计模式面试题,【BAT必备】设计模式面试题,【BAT必备】设计模式面试题,【BAT必备】设计模式面试题
  • Java设计模式面试题

    2021-04-02 09:56:38
    设计模式
  • 10道Java面试必备的设计模式面试题!.zip
  • PAGE 3 1. Java基础部分 基础部分的顺序基本语法类相关的语法内部类的语法继承相关的语法异常的语法线程的语法集合的语法io的语法虚拟机方面的语法 1一个.java"源文件中是否可以包括多个类不是内部类有什么限制 可以...
  • 设计模式面试题(设计模式速成版)

    千次阅读 多人点赞 2021-03-22 16:57:23
    若之前没有学习过设计模式,可以将该文章死记硬背,然后应付面试设计模式详细学习,可以参见 http://c.biancheng.net/view/1317.html 名词解释 设计模式:软件设计模式是对各种面向对象方法的一种总结。前辈们...
  • 23种设计模式分别叫什么名称,如何分类? 分三类: 创建型,行为型,结构型; 创建型包含: 1.单例模式 2.工厂模式 3.建造者模式 4.原型模式 5.工厂方法模式 行为型包含: 1.策略模式 2.模板方法模式 3.观察者模式 4...
  • 设计模式面试题.pdf

    2021-04-07 17:18:50
    设计模式面试题
  • 本压缩包主要内容为c#教程(书籍)及一些经典资料,主要包括...各个公司面试题(214题) 23种设计模式.pdf c++笔试面试宝典2009版.doc 程序员面试宝典.pdf 高质量C++-C编程指南.mht 注意:共有两个分卷,这是分卷2。
  • 设计模式面试题

    2013-12-16 22:36:45
    设计模式面试题,可以看一下,对大家以后去面试有帮助。
  • 什么是设计模式2.为什么要学习设计模式3.设计模式分类4.设计模式的六大原则5.单例模式1.什么是单例2.那些地方用到了单例模式3.单例优缺点4.单例模式使用注意事项:5.单例防止反射漏洞攻击6.如何选择单例创建方式7....
  • java面试题,希望能帮到各位IT工作者!java面试题,希望能帮到各位IT工作者!
  • 23种设计模式(常见面试题

    千次阅读 2021-01-24 15:26:07
    23种设计模式(常见面试题) 1.什么是设计模式? 答: 设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的...
  • 设计模式面试题总结(2022最新版) 关于作者 程序猿周周 ⌨️ 短视频小厂BUG攻城狮 如果文章对你有帮助,记得关注、点赞、收藏,一键三连哦,你的支持将成为我最大的动力 关于本文 本文是 Java 面试总结系列的第...
  • 10道Java面试必备的设计模式面试题!.pdf
  • 设计模式面试|Java面试题

    千次阅读 2020-01-20 15:18:59
    1.请列举出在 JDK 中几个常用设计模式? 单例模式(Singleton pattern)用于 Runtime,Calendar 和其他的一些类中。工厂模式 (Factory pattern)被用于各种不可变的类如 Boolean,像 Boolean.valueOf,观察者...
  • 设计模式面试专题及答案
  • 4. 高频面试题-设计模式-0930443636910739.md
  • 【面试资料】-(机构内训资料)设计模式面试题
  • Java面试题--设计模式

    千次阅读 2019-04-07 12:36:31
    答案以及所有23种设计模式详细介绍,请参考: https://blog.csdn.net/doymm2008/article/details/13288067 设计模式的分类有哪些? 工厂模式: 概念: 实现方法:普通工厂方法、静态工厂方法 使用场景: 有...
  • 1、单例模式是一种常用设计模式,单例模式比较简单但包含了关于线程安全、内存模型、类加载机制等一些比较核心的知识点。 2、单例模式就是在整个运行时域,一个类只有一个实例对象。 3、为什么需要单例模式呢?...
  • java面试题_设计模式(26题).zip
  • Java 常见的面试题设计模式

    千次阅读 2021-05-12 16:22:24
    Java 常见的面试题设计模式

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 144,402
精华内容 57,760
关键字:

常用的设计模式面试题