文章目录
- 高频设计模式
- 单例模式
- 饿汉式(Eager Initialization)
- 懒汉式(Lazy Initialization)
- 双重校验锁(Double-Checked Locking)
- 静态内部类(Static Inner Class)
- 枚举(Enum)
- 工厂模式
- 简单工厂模式
- 工厂方法模式
高频设计模式
设计模式是解决常见问题的模板,它们被广泛应用于软件设计中以提高代码的可重用性、可维护性和可扩展性。以下是一些在Java中高频使用的设计模式:
- 单例模式(Singleton):
确保一个类只有一个实例,并提供一个全局访问点。 - 工厂模式(Factory Method):
定义一个接口用于创建对象,但让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。 - 抽象工厂模式(Abstract Factory):
提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。 - 建造者模式(Builder):
将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。 - 原型模式(Prototype):
通过复制现有的实例来创建新的实例,而不是通过构造函数创建。 - 适配器模式(Adapter):
将一个类的接口转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以一起工作。 - 装饰器模式(Decorator):
动态地给一个对象添加一些额外的职责。就扩展功能而言,装饰器模式比继承更灵活。 - 代理模式(Proxy):
为其他对象提供一种代理以控制对这个对象的访问。 - 外观模式(Facade):
提供一个统一的接口,用来访问子系统中的一群接口,从而让子系统更容易使用。 - 桥接模式(Bridge):
将抽象部分与实现部分分离,使它们都可以独立地变化。 - 组合模式(Composite):
将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使用户对单个对象和组合对象的使用具有一致性。 - 享元模式(Flyweight):
运用共享技术有效地支持大量细粒度的对象。 - 策略模式(Strategy):
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。 - 模板方法模式(Template Method):
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 - 观察者模式(Observer):
当一个对象状态发生改变时,所有依赖于它的对象都得到通知并自动更新。 - 状态模式(State):
允许对象在内部状态改变时改变其行为,对象看起来好像修改了其类。 - 命令模式(Command):
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。 - 责任链模式(Chain of Responsibility):
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。 - 中介者模式(Mediator):
定义一个对象来封装一组对象之间的交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。 - 迭代器模式(Iterator):
提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露其内部的表示。
单例模式
单例模式(Singleton Pattern)是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点来获取该实例。在某些场景下,只有一个实例是很重要的,比如在共享资源或管理共享状态时,只有一个实例可以避免冲突和错误。
在Java中,实现单例模式有多种方式,以下是一些常见的实现方法:
饿汉式(Eager Initialization)
在这种方式中,单例对象在类加载时就被创建。
public class Singleton {private static final Singleton instance = new Singleton();private Singleton() {// 私有构造函数}public static Singleton getInstance() {return instance;}
}
这种方式简单,但可能在类加载时就创建了实例,即使这个实例不会被使用。
懒汉式(Lazy Initialization)
在这种方式中,单例对象在第一次使用时才被创建。
public class Singleton {private static Singleton instance;private Singleton() {// 私有构造函数}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}
这种方式延迟了实例的创建,但它在多线程环境下不是线程安全的。
双重校验锁(Double-Checked Locking)
这种方式结合了懒汉式和同步锁,以确保在多线程环境下只有一个实例被创建。
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变量被初始化成Singleton实例时,多个线程正确地处理instance变量。
静态内部类(Static Inner Class)
这种方式利用Java类加载机制来保证单例对象的唯一性。
public class Singleton {private Singleton() {// 私有构造函数}private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();}public static Singleton getInstance() {return SingletonHolder.INSTANCE;}
}
这种方式是线程安全的,并且只有在调用getInstance()方法时才会创建单例对象。
枚举(Enum)
使用枚举实现单例是最简单的方法,也是实践中推荐的方式。
public enum Singleton {INSTANCE;public void doSomething() {// 执行一些操作}
}
工厂模式
工厂模式(Factory Pattern)是一种创建型设计模式,用于处理对象的创建逻辑。工厂模式定义了一个接口用于创建对象,但让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
在简单工厂模式中,一个工厂类根据传入的参数来决定创建哪一种产品类的实例。而在工厂方法模式中,工厂类本身被抽象化,使得不仅可以通过子类来决定创建哪一种产品类的实例,而且可以进一步将实例化的逻辑委托给子类。
简单工厂模式
简单工厂模式有一个工厂类,根据传入的参数来决定创建哪一种产品类的实例。
public interface Product {void show();
}public class ConcreteProductA implements Product {@Overridepublic void show() {System.out.println("我是产品A");}
}public class ConcreteProductB implements Product {@Overridepublic void show() {System.out.println("我是产品B");}
}public class SimpleFactory {public Product createProduct(String type) {if ("A".equals(type)) {return new ConcreteProductA();} else if ("B".equals(type)) {return new ConcreteProductB();}return null;}
}public class Client {public static void main(String[] args) {SimpleFactory factory = new SimpleFactory();Product productA = factory.createProduct("A");productA.show();Product productB = factory.createProduct("B");productB.show();}
}
工厂方法模式
工厂方法模式将工厂类抽象化,使得不仅可以通过子类来决定创建哪一种产品类的实例,而且可以进一步将实例化的逻辑委托给子类。
public abstract class Factory {abstract public Product createProduct();
}public class ConcreteFactoryA extends Factory {@Overridepublic Product createProduct() {return new ConcreteProductA();}
}public class ConcreteFactoryB extends Factory {@Overridepublic Product createProduct() {return new ConcreteProductB();}
}public class Client {public static void main(String[] args) {Factory factoryA = new ConcreteFactoryA();Product productA = factoryA.createProduct();productA.show();Factory factoryB = new ConcreteFactoryB();Product productB = factoryB.createProduct();productB.show();}
}
工厂模式的好处是它提供了一个统一的接口来创建对象,使得客户端不需要知道具体的类名,从而降低了客户端与具体产品类之间的耦合。这使得添加新产品更加容易,只需要添加一个新的具体产品类和对应的工厂类即可,不需要修改现有的代码。