设计模式面试问题

Java中的设计模式

设计模式是一种在软件开发中常用的解决问题的方法,它提供了一些模板来解决常见的问题。下面是在Java项目中使用的一些设计模式示例:

单例模式(Singleton)

单例模式保证在一个Java应用程序中只有一个对象实例。这个实例可以被访问的方式有很多种。在Java中,如果你想要保证一个类只有一个实例,可以使用单例模式。Spring Boot 中的 Bean 默认为单例模式,也就是一个 Bean 对象只会被创建一次,并在整个应用程序中共享。

实例被访问的方式有以下几种:

直接访问公共静态实例变量

这是最常见和简单的方式,可以直接通过类名来访问单例的静态实例变量。

枚举

枚举是一种非常简单、安全和高效的方式来实现单例模式。在 Java 5 以上,可以使用枚举来创建单例,因为枚举天生就是单例的,且线程安全。

静态工厂方法

除了公共静态实例变量之外,单例模式还可以通过静态工厂方法来提供全局访问,这种方式更加灵活,可以自定义一些逻辑来获取单例对象。

注册表

在单例模式中,注册表是一种创建单例类的方式,它通常被用于创建和维护单例对象。注册表将所有单例对象保存在一个映射表中,每当需要访问单例对象时,注册表会返回该对象的引用。

总之,在使用单例模式的时候,需要选择一个合适的访问方式,并避免出现线程安全问题。

工厂方法模式(Factory Method)

工厂方法模式是一种创建型模式,它用于定义一个创建对象的接口,然后由子类来决定要实例化哪个类。在Java中,工厂方法模式可以被用来创建多个相似的对象。在 Spring Boot 中,使用了工厂模式来创建和管理 Bean 对象。Spring Boot 中的 BeanFactory 、ApplicationContext 都使用了工厂模式来管理 Bean 对象的创建和销毁。

观察者模式(Observer)

观察者模式是一种行为模式,它定义了一个对象之间的一对多的依赖关系。当一个对象发生改变时,所有依赖它的对象都会得到通知。在Java中,观察者模式常用于事件处理、GUI编程等方面。Spring Boot 中的事件驱动模型使用了观察者模式。应用程序中的事件可以触发多个观察者,这些观察者可以是 Spring Bean 或者是独立的 Java 类。在Spring Boot中,常用于处理各种事件,比如在消息队列中,监听并分发消息。

策略模式(Strategy)

策略模式是一种行为模式,它定义了一系列算法和行为,并将它们封装在一个对象中,使得它们可以互相替换。在Java中,策略模式常用于算法决策,例如在排序和搜索算法中,可以使用策略模式来确定使用哪种算法。在 Spring Boot 中,许多组件和框架都使用了策略模式。比如在 Spring Security 中,配置安全策略时可以使用不同的策略来保护资源。

Spring Security 是一个基于 Spring 的安全性框架,它提供了典型的安全性服务,如认证、授权、加密、访问控制等,其中配置安全策略是它最核心的功能之一。

下面列举一些 Spring Security 中可以使用的安全策略:

权限控制策略(Access Control)

Access Control 是 Spring Security 中最基本的安全策略,它用来控制用户对某个资源访问的权限。比如可以通过基于角色的权限控制策略来定义谁可以访问一个资源,谁不可以访问或者谁可以对资源进行修改等。

授权策略(Authorization)

授权策略和权限控制策略类似,但它更加细粒度。在 Spring Security 中,可以通过配置 AccessDecisionManager 和 AccessDecisionVoter 来实现更加复杂的授权策略。比如可以在授权策略中基于 HTTP 请求方法和 URL 等信息进行授权。

身份认证策略(Authentication)

身份认证策略用来验证用户的身份,可以通过用户名/密码等方式进行身份认证,并获取用户所拥有的权限信息。在 Spring Security 中,可以通过配置 AuthenticationProvider 来实现身份认证策略。

安全过滤器策略(Security Filter Chain)

安全过滤器策略用来保护 Web 应用程序中的资源免受未经授权的访问,通常是通过配置一系列安全过滤器来实现的。在 Spring Security 中,可以通过配置 HttpSecurity 来实现安全过滤器策略。

会话管理策略(Session Management)

会话管理策略用来管理用户的会话信息,包括创建、维护和销毁会话等。在 Spring Security 中,可以通过配置 SessionManagementConfigurer 来实现会话管理策略,比如设置会话超时时间、session 固定攻击等。

适配器模式(Adapter)

适配器模式是一种结构模式,它可以将一个类的接口转换成客户端所期望的另一个接口。在Java中,适配器模式常被用于现有类的重用,例如在集合框架中,可以使用适配器模式来将一个Enumeration对象适配成一个Iterator对象。Spring Boot 中的许多组件,比如 Spring Data JPA,都使用了适配器模式。通过适配器模式,可以将不同的数据源适配成为统一的接口,从而方便使用。

原型模式(Prototype)

原型模式是一种创建型模式,它通过复制现有的对象来生成新的对象。在Java中,原型模式常被用于避免创建许多相似的对象,例如在字符串处理中,可以使用原型模式来避免重复创建相同的字符串对象。

装饰器模式(Decorator)

装饰器模式是一种结构模式,它可以动态地给对象添加新的行为或功能。在Java中,装饰器模式常被用于对现有对象进行功能增强,例如在IO流处理中,可以使用装饰器模式来增强流的读写功能。Spring Boot中许多组件也使用了装饰器模式,比如为 JavaEE 对象提供事务支持的 TransactionTemplate 就使用了装饰器模式。

外观模式(Facade)

外观模式是一种结构模式,它为复杂的子系统提供了一个简单的接口。在Java中,外观模式通常被用来隐藏子系统的复杂性,例如在JavaEE开发中,可以使用外观模式来封装复杂的业务逻辑。

访问者模式(Visitor)

访问者模式是一种行为模式,它可以将算法与数据结构分离,使得能够很容易地在不同数据结构上应用算法。在Java中,访问者模式常被用于对复杂的数据结构(例如树状结构)进行遍历和操作。

建造者模式(Builder)

建造者模式可以用来创建复杂对象,通常由多个部分组成。这些部分可以被组装成不同的对象,这是一个灵活的方法。在Java中,建造者模式通常被用来构建复杂的对象,例如在使用Guava库时,需要使用其建造者类来创建集合对象。

代理模式

代理模式是一种常用的结构型设计模式,其特点是在不改变原对象的前提下,通过引入代理对象来访问原对象,从而在代理对象中实现一些额外的操作或限制对原对象的访问。
代理模式主要有三种类型:静态代理、动态代理和 Cglib 代理。
1、静态代理
静态代理是指代理对象在编译时就已经确定的代理方式。静态代理需要代理类和目标类实现同一接口或继承同一抽象类,代理类中包含目标类的实例,并在代理类的方法中调用目标类的方法,同时可以在代理类中添加额外的功能。
静态代理的优点是简单易懂,易于实现;缺点是需要为每个目标类写一个代理类,且代码量较大。
2、动态代理
动态代理是指代理对象在运行时根据需要动态生成的代理方式。动态代理使用 Java 原生 API,通过反射和 InvocationHandler 接口实现。
动态代理和静态代理一样,需要代理类和目标类实现同一接口或继承同一抽象类,代理类的方法中则通过反射调用目标类的方法。与静态代理不同的是,代理类是在运行时动态生成的,因此无需为每个目标类编写代理类。
动态代理的优点是实现灵活简便,可以在运行时动态生成代理对象;缺点是需要了解反射和动态代理的原理和机制,且动态生成代理对象的过程可能会对系统性能产生一定影响。
3、Cglib 代理
Cglib 代理是一种通过字节码技术实现的代理方式,可以实现对没有接口的类的代理。Cglib 代理通过继承被代理的类,然后在运行时动态生成代理类,代理类中包含被代理类的实例,并在代理类的方法中调用被代理类的方法,同时可以在代理类中添加额外的功能。
Cglib 代理的优点是可以对没有接口的类进行代理,代理方式更为灵活;缺点是因为需要生成动态代理类的字节码,所以相对于动态代理,Cglib 代理的性能开销更大。

代理模式在实际应用中有着广泛的应用,例如 Spring 框架中的 AOP(面向切面编程),就是通过代理模式来实现对目标对象的增强和限制。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值