激励案例网站制作,杭州搜索推广公司,腾讯企业邮箱免费注册入口,企业网站设置目录 Java基础 设计模式单例模式工厂模式观察者模式策略模式装饰器模式其他设计模式 Java基础 设计模式 单例模式
单例模式#xff08;Singleton Pattern#xff09; 定义#xff1a;确保一个类只有一个实例#xff0c;并提供一个全局访问点来访问这个实例。适用场景… 目录 Java基础 设计模式单例模式工厂模式观察者模式策略模式装饰器模式其他设计模式 Java基础 设计模式 单例模式
单例模式Singleton Pattern 定义确保一个类只有一个实例并提供一个全局访问点来访问这个实例。适用场景 当系统中某个类只需要一个实例如数据库连接池。因为频繁地创建和销毁数据库连接是非常消耗资源的使用单例模式可以保证整个应用程序中只有一个数据库连接池实例所有需要数据库连接的地方都从这个实例获取连接。配置文件管理器整个应用程序通常只需要一个配置文件管理器来读取和管理配置信息。 示例代码懒汉式单例
class Singleton {private static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance null) {instance new Singleton();}return instance;}
}解释在上述代码中Singleton类的构造函数是私有的这样就防止了其他类直接通过new关键字来创建Singleton类的实例。getInstance方法是获取单例对象的公共方法当instance为null时创建一个新的Singleton实例然后返回这个实例。不过这种懒汉式单例在多线程环境下可能会出现问题因为可能会有多个线程同时判断instance为null从而创建多个实例。可以通过加锁等方式解决这个问题比如使用双重检查锁定DCL - Double - Checked Locking。
工厂模式
工厂模式Factory Pattern 定义定义一个创建对象的接口但让子类决定实例化哪个类。工厂模式把对象的创建和使用分离。适用场景 当对象的创建过程比较复杂比如创建对象需要读取配置文件、连接数据库等操作时。例如在一个游戏开发中游戏角色有多种类型战士、法师、刺客不同类型的角色初始化过程不同使用工厂模式可以将角色创建过程封装在工厂类中。根据不同条件创建不同类型的对象。例如在一个图形绘制系统中根据用户选择绘制不同的图形圆形、矩形、三角形可以使用工厂模式来创建这些图形对象。 示例代码简单工厂模式
// 产品接口
interface Shape {void draw();
}
// 具体产品类 - 圆形
class Circle implements Shape {Overridepublic void draw() {System.out.println(Drawing a circle);}
}
// 具体产品类 - 矩形
class Rectangle implements Shape {Overridepublic void draw() {System.out.println(Drawing a rectangle);}
}
// 工厂类
class ShapeFactory {public Shape getShape(String shapeType) {if (shapeType.equalsIgnoreCase(circle)) {return new Circle();} else if (shapeType.equalsIgnoreCase(rectangle)) {return new Rectangle();}return null;}
}解释Shape是产品接口Circle和Rectangle是具体的产品类它们实现了draw方法。ShapeFactory是工厂类getShape方法根据传入的shapeType字符串来决定创建哪种具体的形状对象。这样当需要创建形状对象时只需要调用工厂类的getShape方法而不需要关心具体对象的创建细节。
观察者模式
观察者模式Observer Pattern 定义定义对象间的一种一对多的依赖关系当一个对象的状态发生改变时所有依赖于它的对象都得到通知并被自动更新。适用场景 消息推送系统当有新的消息产生时所有订阅了该消息类型的用户观察者都会收到通知。例如在一个新闻发布系统中当有新的新闻发布时订阅了该新闻频道的用户会收到更新通知。GUI编程中的事件处理例如按钮点击事件。当按钮被观察对象被点击时所有注册到这个按钮的事件监听器观察者都会收到通知并执行相应的操作。 示例代码
import java.util.ArrayList;
import java.util.List;
// 被观察主题接口
interface Subject {void registerObserver(Observer o);void removeObserver(Observer o);void notifyObservers();
}
// 观察者接口
interface Observer {void update(String message);
}
// 具体被观察主题 - 消息发布者
class MessagePublisher implements Subject {private ListObserver observers new ArrayList();private String message;Overridepublic void registerObserver(Observer o) {observers.add(o);}Overridepublic void removeObserver(Observer o) {observers.remove(o);}Overridepublic void notifyObservers() {for (Observer observer : observers) {observer.update(message);}}public void setMessage(String message) {this.message message;notifyObservers();}
}
// 具体观察者 - 用户
class User implements Observer {private String name;public User(String name) {this.name name;}Overridepublic void update(String message) {System.out.println(name received message: message);}
}解释Subject是被观察主题接口定义了注册观察者、移除观察者和通知观察者的方法。Observer是观察者接口update方法用于接收被观察对象的状态更新消息。MessagePublisher是具体的被观察主题它维护了一个观察者列表当消息更新通过setMessage方法时会遍历观察者列表并调用每个观察者的update方法。User是具体的观察者实现了update方法来处理接收到的消息。
策略模式
策略模式Strategy Pattern 定义定义一系列算法将每个算法封装起来并使它们可以相互替换。策略模式让算法的变化独立于使用它的客户。适用场景 电商系统中的折扣计算。例如在促销活动中可能有不同的折扣策略如满减折扣、百分比折扣、固定金额折扣等。可以将这些折扣计算方法封装成不同的策略类根据不同的促销活动选择合适的策略。排序算法的选择。系统中有多种排序算法冒泡排序、快速排序、归并排序根据数据的特点和性能要求选择不同的排序策略。 示例代码
// 策略接口
interface DiscountStrategy {double calculateDiscount(double price);
}
// 具体策略 - 百分比折扣
class PercentageDiscount implements DiscountStrategy {private double discountRate;public PercentageDiscount(double discountRate) {this.discountRate discountRate;}Overridepublic double calculateDiscount(double price) {return price * discountRate;}
}
// 具体策略 - 固定金额折扣
class FixedAmountDiscount implements DiscountStrategy {private double fixedDiscount;public FixedAmountDiscount(double fixedDiscount) {this.fixedDiscount fixedDiscount;}Overridepublic double calculateDiscount(double price) {return fixedDiscount;}
}
// 上下文类
class ShoppingCart {private DiscountStrategy discountStrategy;public ShoppingCart(DiscountStrategy discountStrategy) {this.discountStrategy discountStrategy;}public double calculateTotalDiscount(double price) {return discountStrategy.calculateDiscount(price);}
}解释DiscountStrategy是策略接口定义了calculateDiscount方法用于计算折扣。PercentageDiscount和FixedAmountDiscount是具体的策略类分别实现了百分比折扣和固定金额折扣的计算方法。ShoppingCart是上下文类它包含一个DiscountStrategy类型的成员变量通过构造函数注入具体的策略对象calculateTotalDiscount方法使用注入的策略对象来计算折扣。这样当需要改变折扣策略时只需要创建不同的策略对象并注入到ShoppingCart中即可。
装饰器模式
装饰器模式Decorator Pattern 定义动态地给一个对象添加一些额外的职责。就扩展功能而言它比继承更灵活。适用场景 给一个基本的输入/输出流添加缓冲、加密等功能。例如在文件读取时可能先需要对文件内容进行缓冲读取BufferedInputStream也可能需要对读取的内容进行加密处理自定义加密装饰器可以使用装饰器模式来动态地添加这些功能。咖啡店的饮品定制。一杯咖啡基本饮品可以添加奶泡、焦糖、香草等配料装饰来定制口味每种配料都可以看作是一个装饰器通过不断地添加装饰器来实现不同的饮品组合。 示例代码简单的饮品装饰器示例
// 饮品接口
interface Beverage {double cost();
}
// 具体饮品 - 咖啡
class Coffee implements Beverage {Overridepublic double cost() {return 5.0;}
}
// 装饰器抽象类
abstract class CondimentDecorator implements Beverage {protected Beverage beverage;public CondimentDecorator(Beverage beverage) {this.beverage beverage;}
}
// 具体装饰器 - 奶泡
class MilkFoamDecorator extends CondimentDecorator {public MilkFoamDecorator(Beverage beverage) {super(beverage);}Overridepublic double cost() {return beverage.cost() 1.0;}
}
// 具体装饰器 - 焦糖
class CaramelDecorator extends CondimentDecorator {public CaramelDecorator(Beverage beverage) {super(beverage);}Overridepublic double cost() {return beverage.cost() 0.5;}
}解释Beverage是饮品接口定义了cost方法用于计算饮品价格。Coffee是具体的饮品类。CondimentDecorator是装饰器抽象类它实现了Beverage接口并且包含一个Beverage类型的成员变量用于保存被装饰的饮品对象。MilkFoamDecorator和CaramelDecorator是具体的装饰器类它们在cost方法中先调用被装饰饮品的cost方法然后再加上自己添加的配料的价格。这样就可以通过不断地用装饰器包装饮品对象来动态地添加功能和计算价格。例如MilkFoamDecorator(new CaramelDecorator(new Coffee())).cost()这样的调用就可以计算出一杯加了奶泡和焦糖的咖啡的价格。
其他设计模式
上文五种设计模式是比较常用的但很难绝对地说它们是“最常用”的。 从使用频率角度看 在实际的软件开发中单例模式用于管理共享资源如日志系统、配置管理器等其使用频率较高。许多框架和应用程序都需要确保某些关键对象在整个生命周期内只有一个实例以保证资源的有效利用和数据的一致性。工厂模式有助于解耦对象的创建和使用在对象创建过程复杂或者需要根据不同条件创建不同对象的场景下被广泛应用。比如在大型企业级应用开发中经常会用到工厂模式来创建各种业务对象。观察者模式在事件驱动的编程场景下非常实用像图形用户界面GUI开发、消息队列系统等领域大量使用。随着软件系统的交互性越来越复杂观察者模式的应用也越来越广泛。策略模式用于实现算法的灵活替换在需要根据不同情况选择不同算法或行为的场景下发挥重要作用。例如在金融系统中计算利息的不同策略或者游戏中角色行为的不同策略选择等场景经常会用到。装饰器模式对于动态地扩展对象功能很有帮助在Java的输入/输出流处理以及一些具有可定制功能的对象设计中较为常用如Web开发中的请求和响应处理也可以通过装饰器模式来添加诸如缓存、安全验证等额外功能。 其他常用的设计模式还有 代理模式Proxy Pattern 适用场景 远程代理用于代表一个远程对象隐藏网络通信等细节。例如在分布式系统中一个本地对象代表远程服务器上的对象进行方法调用通过网络通信获取远程对象的数据或执行远程对象的操作。虚拟代理用于延迟加载资源。比如在网页加载图片时如果图片很大可以先使用一个占位符虚拟代理显示当真正需要显示图片细节时比如图片进入可视区域再加载实际的图片资源。 模板方法模式Template Method Pattern 适用场景 框架开发中定义算法的骨架让子类去实现某些具体步骤。例如在一个游戏开发框架中游戏的启动流程加载资源、初始化场景、开始游戏循环等可以通过模板方法模式定义不同类型的游戏如角色扮演游戏、射击游戏可以继承这个模板并实现自己特定的加载资源和初始化场景的方式。 外观模式Facade Pattern 适用场景 用于为复杂的子系统提供一个简单统一的接口。例如在一个计算机系统中启动计算机涉及到多个硬件设备和软件系统的启动和初始化CPU、内存、硬盘、操作系统等可以通过外观模式提供一个简单的“启动计算机”的接口将内部复杂的操作封装起来方便用户使用。
这几种设计模式也都有各自特定的适用场景在很多软件系统的设计和开发中都发挥着重要作用。具体哪种设计模式最常用还会因不同的业务领域、软件规模、开发团队的习惯等因素而有所不同。