单例模式示例
单例模式是一种常用的软件设计模式,其目的是确保一个类只有一个实例,并提供一个全局访问点。以下是一个简单的单例模式示例:
java
public class Singleton {
// 私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载
private static Singleton instance = null;
// 私有构造方法,防止被实例化
private Singleton() {
}
// 静态工厂方法,创建实例
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
在这个例子中,Singleton 类有一个私有的静态变量 instance,它用于存储类的唯一实例。Singleton 类有一个私有的构造方法,防止外部通过 new 关键字创建实例。getInstance 方法用于返回 instance 变量的值,如果 instance 为 null,则创建一个新的 Singleton 实例并返回。
这种方式实现的单例模式被称为“懒汉模式”,因为实例是在第一次调用 getInstance 方法时创建的。这种方式的优点是实现了延迟加载,但缺点是在多线程环境下可能会创建多个实例。为了解决这个问题,可以使用“双重检查锁定”模式:
java
复制
public class Singleton {
// 私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载
private static volatile Singleton instance = null;
// 私有构造方法,防止被实例化
private Singleton() {
}
// 静态工厂方法,创建实例
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class ) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
在这个例子中,instance 变量被声明为 volatile,以确保在多线程环境下,instance 的值在第一次创建后不会被重排序。这样可以保证 instance 的值在多线程环境下的一致性。
策略模式示例
以下是一个使用Java实现策略模式的简单示例,展示了策略模式的应用场景。
首先定义一个接口,表示商品的促销策略:
```java
public interface PromotionStrategy {
double applyPromotion(double price);
}
```
然后实现具体的促销策略类:
```java
public class NormalPromotion implements PromotionStrategy {
@Override
public double applyPromotion(double price) {
return price;
}
}
public class DiscountPromotion implements PromotionStrategy {
private double discountRate;
public DiscountPromotion(double discountRate) {
this.discountRate = discountRate;
}
@Override
public double applyPromotion(double price) {
return price * (1 - discountRate);
}
}
public class FullReductionPromotion implements PromotionStrategy {
private double fullAmount;
private double reductionAmount;
public FullReductionPromotion(double fullAmount, double reductionAmount) {
this.fullAmount = fullAmount;
this.reductionAmount = reductionAmount;
}
@Override
public double applyPromotion(double price) {
if (price >= fullAmount) {
return price - reductionAmount;
}
return price;
}
}
```
最后,在商品类中使用策略模式:
```java
public class Product {
private String name;
private double price;
private PromotionStrategy promotionStrategy;
public Product(String name, double price, PromotionStrategy promotionStrategy) {
this.name = name;
this.price = price;
this.promotionStrategy = promotionStrategy;
}
public double applyPromotion() {
return promotionStrategy.applyPromotion(price);
}
public static void main(String[] args) {
Product product = new Product("iPhone", 1000, new NormalPromotion());
System.out.println(product.applyPromotion()); // 输出 1000
product = new Product("iPhone", 1000, new DiscountPromotion(0.2));
System.out.println(product.applyPromotion()); // 输出 800
product = new Product("iPhone", 1000, new FullReductionPromotion(800, 100));
System.out.println(product.applyPromotion()); // 输出 700
}
}
```
在这个示例中,通过使用策略模式,我们实现了不同的促销策略类并应用在商品类中,从而使得商品类的促销策略可以灵活地切换。这种方式下,商品类不需要直接实现具体的促销算法,而是通过组合不同的促销策略对象来实现不同的促销方式。
以上是一个简单的策略模式的Java实现示例,希望对您理解策略模式有所帮助。在实际应用中,您可以根据具体需求设计和实现不同的策略类,从而实现更加灵活和可扩展的系统设计。
代理模式示例
以下是一个使用Java实现代理模式的简单示例,展示了静态代理的应用场景。
首先定义一个接口,表示需要代理的服务:
```java
public interface DataService {
void fetchData();
}
```
然后实现具体的服务类:
```java
public class DataServiceImpl implements DataService {
@Override
public void fetchData() {
System.out.println("从数据库中获取数据");
}
}
```
接着定义一个代理类,用于代理服务类的操作:
```java
public class DataProxy implements DataService {
private final DataService dataService;
public DataProxy(DataService dataService) {
this.dataService = dataService;
}
@Override
public void fetchData() {
System.out.println("代理类在调用服务前进行日志记录");
dataService.fetchData();
System.out.println("代理类在调用服务后进行日志记录");
}
}
```
最后,在客户端代码中使用代理对象来访问服务对象:
```java
public class Main {
public static void main(String[] args) {
DataService realService = new DataServiceImpl();
DataProxy proxy = new DataProxy(realService);
proxy.fetchData();
}
}
```
在这个示例中,`DataServiceImpl`是具体的服务类,实现了`DataService`接口中的`fetchData`方法。`DataProxy`是代理类,通过组合一个实际的服务对象`DataService`来代理其操作,并在调用服务前后添加了日志记录的功能。在`Main`类中创建了实际的服务对象和代理对象,通过代理对象来访问服务对象。
这样,代理模式帮助我们控制和管理对服务对象的访问,并可以在代理类中添加额外的功能,而不影响实际服务类的代码。这种方式有助于降低耦合度、提高安全性和可维护性。
希望这个示例能帮助理解Java中代理模式的应用。您可以根据实际需求,在更复杂的场景下灵活运用代理模式。