设计模式
策略模式
假设我们有一个商场销售系统,可以根据不同的促销策略来计算商品的实际价格。我们可以使用策略模式来实现这个功能。首先,我们需要定义一个策略接口,如下所示:
1 2 3
| public interface DiscountStrategy { double calculateDiscount(double price); }
|
然后,我们可以定义不同的具体策略类,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class NormalDiscountStrategy implements DiscountStrategy { @Override public double calculateDiscount(double price) { return price; } }
public class VipDiscountStrategy implements DiscountStrategy { @Override public double calculateDiscount(double price) { return price * 0.8; } }
public class SuperVipDiscountStrategy implements DiscountStrategy { @Override public double calculateDiscount(double price) { return price * 0.7; } }
|
接下来,我们可以定义一个上下文类,用于管理不同的策略对象,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class DiscountContext { private DiscountStrategy discountStrategy;
public DiscountContext(DiscountStrategy discountStrategy) { this.discountStrategy = discountStrategy; }
public void setDiscountStrategy(DiscountStrategy discountStrategy) { this.discountStrategy = discountStrategy; }
public double calculateDiscount(double price) { return discountStrategy.calculateDiscount(price); } }
|
最后,我们可以在客户端代码中使用上下文类来计算商品的实际价格,如下所示:
1 2 3 4 5 6 7 8 9 10 11
| DiscountContext context = new DiscountContext(new NormalDiscountStrategy()); double price = context.calculateDiscount(100.0); System.out.println(price);
context.setDiscountStrategy(new VipDiscountStrategy()); price = context.calculateDiscount(100.0); System.out.println(price);
context.setDiscountStrategy(new SuperVipDiscountStrategy()); price = context.calculateDiscount(100.0); System.out.println(price);
|
这样,我们就可以根据不同的促销策略来计算商品的实际价格了。
单例模式
单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供了一个全局访问点来访问该实例。在Java中,实现单例模式有多种方式,下面是几个经典的Java代码案例:
- 饿汉式单例模式
1 2 3 4 5 6 7 8 9
| public class Singleton { private static Singleton instance = new Singleton(); private Singleton() {} public static Singleton getInstance() { return instance; } }
|
这种方式是最简单的实现方式,它在类加载时就创建了实例,因此线程安全。但它可能会浪费一些内存,因为实例在任何时候都会被创建,无论是否需要。
- 懒汉式单例模式
1 2 3 4 5 6 7 8 9 10 11 12
| public class Singleton { private static Singleton instance; private Singleton() {} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
|
这种方式是在需要时才创建实例,避免了浪费内存,但是在多线程环境下可能会出现问题,需要加锁来保证线程安全。
- 双重检查锁定单例模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 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; } }
|
这种方式在懒汉式单例模式的基础上加了双重检查锁定,避免了多线程环境下的问题,并且在第一次创建实例后就不再需要加锁,性能更好。
- 静态内部类单例模式
1 2 3 4 5 6 7 8 9 10 11
| public class Singleton { private Singleton() {} private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.INSTANCE; } }
|
这种方式利用了Java中静态内部类的特性,在需要时才创建实例,并且保证了线程安全。它也是目前最为常用的单例模式实现方式之一。
枚举类单例模式
枚举类单例模式是一种比较简单且有效的单例模式实现方式。在Java中,枚举类是一种特殊的类,它可以定义一组有限的常量,并且这些常量在整个应用程序中都是唯一的。因此,我们可以利用枚举类的这个特性来实现单例模式。
在枚举类中,只需要定义一个枚举常量即可。这个枚举常量就是我们要实现的单例对象。由于枚举常量在整个应用程序中都是唯一的,因此我们可以将它看作是一个单例对象。下面是一个简单的枚举类单例模式的示例:
1 2 3 4 5 6 7
| public enum Singleton { INSTANCE;
public void doSomething() { } }
|
在上面的示例中,我们定义了一个名为Singleton
的枚举类,并且在其中定义了一个名为INSTANCE
的枚举常量。由于枚举常量在整个应用程序中都是唯一的,因此INSTANCE
就是我们要实现的单例对象。
使用枚举类单例模式时,我们可以通过Singleton.INSTANCE
来获取单例对象,并调用它的方法来完成相应的操作。由于枚举类单例模式是线程安全的,因此可以在多线程环境下使用。