全文目录:
开篇语
今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。
我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。
小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!
前言
设计模式,是面向对象设计中的“秘籍”,帮助我们解决程序设计中遇到的一些常见问题。它们是基于多年开发经验总结出来的解决方案,不仅能提升代码的复用性、可维护性和扩展性,还能使我们在开发过程中避免重复造轮子。在Java中,设计模式的应用更是几乎无处不在,帮助我们优化架构、提升开发效率。
今天我们将重点讲解几个常见的设计模式,具体包括单例模式、工厂模式,以及其他一些经典的设计模式,如观察者模式、策略模式和适配器模式。在这个过程中,我们不仅要知道“为什么”使用这些模式,更要知道“如何”使用它们。
1. 单例模式:确保全局只有一个实例
单例模式是一个非常常见的设计模式,它的核心思想是:保证一个类只有一个实例,并提供一个全局的访问点。这个模式特别适用于控制资源的使用,比如数据库连接池、线程池等。单例模式不仅能避免多个实例造成的资源浪费,还能控制类的实例化过程,确保一致性。
1.1 饿汉式单例
饿汉式单例是在类加载时就创建单例对象,因此它是线程安全的,且实现简单。但是,这种方式缺点在于,不管是否需要该实例,类加载时就会进行实例化。
public class Singleton {
// 在类加载时初始化实例
private static final Singleton INSTANCE = new Singleton();
// 私有化构造函数
private Singleton() {}
// 提供公共方法获取实例
public static Singleton getInstance() {
return INSTANCE;
}
}
这种方式的缺点是:如果你只在某些情况下需要这个单例实例,它依然会在类加载时就创建好,这可能造成性能上的浪费。不过,它在高并发场景下是线程安全的。
1.2 懒汉式单例
懒汉式单例则是在需要的时候才实例化对象,这样可以避免不必要的资源浪费。然而,懒汉式单例在并发场景下存在问题,可能导致多线程下创建多个实例。
public class Singleton {
// 声明静态变量,但不初始化
private static Singleton instance;
// 私有化构造函数
private Singleton() {}
// 提供公共方法获取实例
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
上面的代码在多线程环境下会出现问题,如果多个线程同时进入getInstance()
方法,可能会导致多个实例的创建。为了避免这种情况,我们使用sychronized
进行同步。但是,性能上并不是最优。
1.3 双重检查锁定(DCL)
双重检查锁定(Double-Checked Locking)是为了优化懒汉式单例的性能问题。它通过两次检查instance
是否为空,第一次检查是在同步块外部,第二次检查则是在同步块内部。这种方式既能保证线程安全,又能避免每次都进行同步,提升了性能。
public class Singleton {
private static volatile Singleton instance;
// 私有化构造函数
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
volatile
关键字用于保证instance
变量在多线程环境下的可见性,确保所有线程都能看到最新的instance
值。双重检查锁定提供了较高的性能,是懒汉式单例的优化版本。
2. 工厂模式:简化对象创建
工厂模式是一种创建对象的设计模式,目的是为了将对象的创建过程与使用过程分离,从而提高代码的可维护性和扩展性。工厂模式的基本思想是定义一个用于创建对象的接口,由具体的工厂类实现该接口。
2.1 简单工厂模式
简单工厂模式又叫静态工厂方法,它通过一个工厂类来决定哪个类的实例应该被创建。工厂类根据不同的条件(如传入的参数)来返回不同的对象。
public class AnimalFactory {
public static Animal createAnimal(String type) {
if ("Dog".equals(type)) {
return new Dog();
} else if ("Cat".equals(type)) {
return new Cat();
}
return null;
}
}
在这个简单的工厂模式中,AnimalFactory
类根据传入的type
来决定返回哪个具体的动物实例。该模式的缺点是,如果新增了一个Animal
子类,我们需要修改工厂方法,违背了开闭原则。
2.2 工厂方法模式
工厂方法模式是对简单工厂模式的进一步抽象。每一个具体的工厂都继承自一个抽象工厂类,通过不同的工厂来创建对象。这样一来,当需要新增一个产品时,我们只需要新增一个工厂类,而不需要修改原有代码,符合开闭原则。
public abstract class AnimalFactory {
public abstract Animal createAnimal();
}
public class DogFactory extends AnimalFactory {
@Override
public Animal createAnimal() {
return new Dog();
}
}
public class CatFactory extends AnimalFactory {
@Override
public Animal createAnimal() {
return new Cat();
}
}
2.3 抽象工厂模式
抽象工厂模式进一步扩展了工厂方法模式,它不仅能生产一个产品类别的对象,还能生产多个相关的对象。例如,一个“动物工厂”可能不仅仅生产狗、猫,还可以生产它们的相关对象,如“狗的玩具”或“猫的食品”。
public interface AnimalFactory {
Animal createAnimal();
Toy createToy();
}
public class DogFactory implements AnimalFactory {
public Animal createAnimal() {
return new Dog();
}
public Toy createToy() {
return new DogToy();
}
}
通过这种方式,我们不仅可以创建不同类型的动物,还能创建与动物相关的产品。抽象工厂模式使得我们能够在多个产品族之间进行切换,且能够扩展更多产品类别而无需修改现有代码。
3. 其他设计模式
3.1 观察者模式
观察者模式是一种行为型设计模式,主要用于对象间的一对多关系,当一个对象的状态发生改变时,所有依赖它的对象都会得到通知并自动更新。观察者模式广泛应用于事件驱动系统,比如GUI系统中的事件监听,或者消息推送等场景。
public interface Observer {
void update(String message);
}
public class ConcreteObserver implements Observer {
private String name;
public ConcreteObserver(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name + " received: " + message);
}
}
public class Subject {
private List<Observer> observers = new ArrayList<>();
public void addObserver(Observer observer) {
observers.add(observer);
}
public void notifyObservers(String message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}
3.2 策略模式
策略模式是一种行为型设计模式,定义了一系列算法,并将每一个算法封装起来,使它们可以互相替换。策略模式让算法的变化独立于使用算法的客户。
public interface PaymentStrategy {
void pay();
}
public class CreditCardPayment implements PaymentStrategy {
@Override
public void pay() {
System.out.println("Paying with Credit Card");
}
}
public class PayPalPayment implements PaymentStrategy {
@Override
public void pay() {
System.out.println("Paying with PayPal");
}
}
3.3 适配器模式
适配器模式是一种结构型设计模式,允许我们将一个类的接口转换成客户希望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起工作。
public interface MediaPlayer {
void play(String fileName);
}
public class AudioPlayer implements MediaPlayer {
@Override
public void play(String fileName) {
System.out.println("Playing audio: " + fileName);
}
}
public interface AdvancedMediaPlayer {
void playMP4(String fileName);
}
public class MP4Player implements AdvancedMediaPlayer {
@Override
public void playMP4(String fileName) {
System.out.println("Playing MP4: " + fileName);
}
}
public class MediaAdapter implements MediaPlayer {
private AdvancedMediaPlayer advancedMusicPlayer;
public MediaAdapter(AdvancedMediaPlayer advancedMusicPlayer) {
this.advancedMusicPlayer = advancedMusicPlayer;
}
@Override
public void play(String fileName) {
advancedMusicPlayer.playMP4(fileName);
}
}
4. 结语
设计模式的应用,可以帮助我们更好地管理复杂的系统结构,提升代码的灵活性、可维护性和可扩展性。在实际开发中,根据具体需求合理选用不同的设计模式,能让我们的代码更加优雅和高效。希望今天的内容能帮助你对这些经典设计模式有更深入的理解,并在实际开发中游刃有余地运用它们!
… …
文末
好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。
… …
学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!
wished for you successed !!!
⭐️若喜欢我,就请关注我叭。
⭐️若对您有用,就请点赞叭。
⭐️若有疑问,就请评论留言告诉我叭。
版权声明:本文由作者原创,转载请注明出处,谢谢支持!