Java七种常用设计模式

1、单例模式(Singleton Pattern)

单例模式是(Singleton Pattern)Java中最常用的设计模式之一,它保证一个类仅有一个实例,并提供一个全局访问点。

实现单例模式的核心是将类的构造方法私有化,以防止外部直接通过构造函数创建实例。同时,类内部需要提供一个静态方法或变量来获取该类的唯一实例。

以下是一个简单的单例模式实现:

public class Singleton {
    private static Singleton instance = null;

    // 私有构造方法
    private Singleton() {
    }

    // 静态方法,获取唯一实例
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

2、工厂模式(Factory Pattern)

工厂模式(Factory Pattern)是Java中常用的一种创建型设计模式,它提供了一种将对象创建的过程封装起来的方法,可以根据不同的参数来创建不同类型的对象。

工厂模式有三种常用的实现方式:简单工厂模式、工厂方法模式和抽象工厂模式。以简单工厂模式为例,实现过程如下:

  1. 定义抽象产品类:
public abstract class Product {
    public abstract void use();
}
  1. 定义具体产品类:
public class ProductA extends Product {
    @Override
    public void use() {
        System.out.println("使用产品A");
    }
}

public class ProductB extends Product {
    @Override
    public void use() {
        System.out.println("使用产品B");
    }
}
  1. 定义工厂类:
public class Factory {
    public static Product createProduct(String type) {
        if ("A".equals(type)) {
            return new ProductA();
        } else if ("B".equals(type)) {
            return new ProductB();
        } else {
            throw new IllegalArgumentException("无效的产品类型");
        }
    }
}
  1. 调用工厂类创建产品:
Product productA = Factory.createProduct("A");
productA.use(); // 输出:使用产品A

Product productB = Factory.createProduct("B");
productB.use(); // 输出:使用产品B

在上述实现中,AbstractProduct是一个抽象产品类,定义了产品的基本属性和方法。ProductAProductB是具体的产品类,实现了抽象产品类中定义的方法。

Factory是一个工厂类,根据不同的参数创建不同类型的产品对象。Factory中的方法是静态的,无需先创建工厂对象再调用方法。

通过使用工厂模式,可以有效地封装对象的创建过程,实现了高内聚、低耦合的设计思想,也使得代码更加易于维护和扩展。

3、抽象工厂模式(Abstract Factory Pattern)

抽象工厂模式(Abstract Factory Pattern)是Java中常用的一种创建型设计模式,它提供了一种创建一系列相关或相互依赖的对象接口,而无需指定它们具体的类。

抽象工厂模式和工厂方法模式类似,不同之处在于抽象工厂模式中工厂类不单独生产一种产品,而是生产一系列相关的产品。

以下是一个简单的抽象工厂模式实现:

  1. 定义抽象产品类:
public interface AbstractProductA {
    void use();
}

public interface AbstractProductB {
    void consume();
}
  1. 定义具体产品类:
public class ProductA1 implements AbstractProductA {
    @Override
    public void use() {
        System.out.println("使用ProductA1");
    }
}

public class ProductA2 implements AbstractProductA {
    @Override
    public void use() {
        System.out.println("使用ProductA2");
    }
}

public class ProductB1 implements AbstractProductB {
    @Override
    public void consume() {
        System.out.println("消费ProductB1");
    }
}

public class ProductB2 implements AbstractProductB {
    @Override
    public void consume() {
        System.out.println("消费ProductB2");
    }
}
  1. 定义抽象工厂类:
public interface AbstractFactory {
    AbstractProductA createProductA();

    AbstractProductB createProductB();
}
  1. 定义具体工厂类:
public class Factory1 implements AbstractFactory {
    @Override
    public AbstractProductA createProductA() {
        return new ProductA1();
    }

    @Override
    public AbstractProductB createProductB() {
        return new ProductB1();
    }
}

public class Factory2 implements AbstractFactory {
    @Override
    public AbstractProductA createProductA() {
        return new ProductA2();
    }

    @Override
    public AbstractProductB createProductB() {
        return new ProductB2();
    }
}
  1. 调用抽象工厂生成产品:
AbstractFactory factory1 = new Factory1();
AbstractProductA productA1 = factory1.createProductA();
AbstractProductB productB1 = factory1.createProductB();
productA1.use(); // 输出:使用ProductA1
productB1.consume(); // 输出:消费ProductB1

AbstractFactory factory2 = new Factory2();
AbstractProductA productA2 = factory2.createProductA();
AbstractProductB productB2 = factory2.createProductB();
productA2.use(); // 输出:使用ProductA2
productB2.consume(); // 输出:消费ProductB2

以上是一个简单的抽象工厂模式实现。其中,抽象工厂类AbstractFactory定义抽象方法createProductA()createProductB(),用于创建AbstractProductAAbstractProductB类型的对象。

具体工厂类Factory1Factory2分别实现AbstractFactory接口,并实现了接口中定义的两个抽象方法,分别生产ProductA1ProductB1ProductA2ProductB2类型的对象。

通过使用抽象工厂模式,可以更加灵活地生成一系列相关的产品。它能够隔离类的实例化过程,客户端使用抽象工厂创建的对象是一系列相关的产品,无需关心具体的实现。

4、建造者模式(Builder Pattern)

建造者模式(Builder Pattern)是Java中常用的一种创建型设计模式,它将一个复杂的对象的构建过程和表示分离开来,使得同样的构建过程可以创建不同的表示。

建造者模式主要由4部分组成:抽象建造者、具体建造者、指挥者和产品。其中,抽象建造者和具体建造者用于定义和实现产品的创建过程,指挥者协调建造者来构建产品,而产品则是最终构建出的对象。

以下是一个简单的建造者模式实现:

  1. 定义产品类:
public class Product {
    private String partA;
    private String partB;
    private String partC;

    public String getPartA() {
        return partA;
    }

    public void setPartA(String partA) {
        this.partA = partA;
    }

    public String getPartB() {
        return partB;
    }

    public void setPartB(String partB) {
        this.partB = partB;
    }

    public String getPartC() {
        return partC;
    }

    public void setPartC(String partC) {
        this.partC = partC;
    }

    @Override
    public String toString() {
        return "Product{" +
                "partA='" + partA + '\'' +
                ", partB='" + partB + '\'' +
                ", partC='" + partC + '\'' +
                '}';
    }
}
  1. 定义抽象建造者类:
public abstract class Builder {
    public abstract void buildPartA();

    public abstract void buildPartB();

    public abstract void buildPartC();

    public abstract Product getResult();
}
  1. 定义具体建造者类:
public class ConcreteBuilder extends Builder {
    private Product product = new Product();

    @Override
    public void buildPartA() {
        product.setPartA("PartA");
    }

    @Override
    public void buildPartB() {
        product.setPartB("PartB");
    }

    @Override
    public void buildPartC() {
        product.setPartC("PartC");
    }

    @Override
    public Product getResult() {
        return product;
    }
}
  1. 定义指挥者类:
public class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    public void construct() {
        builder.buildPartA();
        builder.buildPartB();
        builder.buildPartC();
    }
}
  1. 创建产品:
Builder builder = new ConcreteBuilder();
Director director = new Director(builder);
director.construct();
Product product = builder.getResult();
System.out.println(product);

在上述实现中,Product是一个产品类,该类具有多个属性,通过访问器和修改器可以进行属性的获取和设置。

Builder是一个抽象建造者类,定义了产品的构建方法。具体建造者类ConcreteBuilder实现了建造者接口中的所有方法,实现了对产品的创建过程。Director是一个指挥者类,负责控制整个建造过程的进行。

最后,通过建造者模式创建产品。指挥者将具体的建造过程委托给建造者完成,而建造者根据指挥者提供的具体信息来创建不同的产品。通过使用建造者模式,可以灵活地构建具有复杂结构的产品。

5、策略模式(Strategy Pattern)

策略模式(Strategy Pattern)是Java中常用的一种行为型设计模式,它定义了一系列算法,将每个算法封装起来,并且使它们可以互换,让算法独立于使用它的客户端而变化。

策略模式主要由三部分组成:策略接口、具体策略类和上下文类。策略接口定义了算法的统一接口,具体策略类实现了策略接口中定义的算法,而上下文类持有一个策略接口的引用,负责调用具体策略类中的算法。

以下是一个简单的策略模式实现:

  1. 定义策略接口:
public interface Strategy {
    void execute();
}
  1. 定义具体策略类:
public class StrategyA implements Strategy {
    @Override
    public void execute() {
        System.out.println("执行策略A");
    }
}

public class StrategyB implements Strategy {
    @Override
    public void execute() {
        System.out.println("执行策略B");
    }
}
  1. 定义上下文类:
public class Context {
    private Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }

    public void doStrategy() {
        strategy.execute();
    }
}
  1. 使用策略模式:
Strategy strategyA = new StrategyA();
Context context = new Context(strategyA);
context.doStrategy(); // 输出:执行策略A

Strategy strategyB = new StrategyB();
context.setStrategy(strategyB);
context.doStrategy(); // 输出:执行策略B

在上述实现中,Strategy是一个抽象策略接口,定义了算法的统一接口。具体策略类StrategyAStrategyB实现了策略接口中的算法,为策略模式提供了具体的算法实现。

Context是一个上下文类,持有一个策略接口的引用,用于调用具体策略类中的算法。通过setStrategy()方法可以动态地改变策略,达到不同的行为。

6、装饰器模式(Decorator Pattern)

装饰器模式(Decorator Pattern)是一种结构型设计模式,用于动态地向一个对象添加一些额外的行为而不需要修改原来的类。

在该模式中,定义了一个装饰器类和一个组件类,被装饰对象是指该组件类及其子类的实例对象,装饰器类和被装饰对象具有相同的父类,即装饰器类和被装饰对象都是通过实现相同的接口或继承相同的抽象类来实现。

在实现时,装饰器类包含一个被装饰对象的成员变量,并维护一个指向被装饰对象的引用,在装饰器类中调用被装饰对象的方法时,还可以添加一些新的功能。

以下是简单的装饰器模式示例代码:

// 抽象组件
interface Component {
    void operation();
}
 
// 具体组件
class ConcreteComponent implements Component {
    public void operation() {
        System.out.println("基础操作");
    }
}

// 抽象装饰器
class Decorator implements Component {
    protected Component component;
 
    public Decorator(Component component) {
        this.component = component;
    }
 
    public void operation() {
        component.operation();
    }
}
 
// 具体装饰器
class ConcreteDecorator extends Decorator {
    public ConcreteDecorator(Component component) {
        super(component);
    }
 
    public void operation() {
        super.operation();
        addedBehavior();
    }
 
    public void addedBehavior() {
        System.out.println("添加额外的行为");
    }
}

在上面的代码中,Component是被装饰对象的抽象接口,ConcreteComponent是具体的被装饰对象。在Decorator中,传入被装饰对象进行初始化,并重写operation()方法。而ConcreteDecorator是具体的装饰器,它继承自Decorator并扩展了被装饰对象的行为。

以下是测试装饰器的示例代码:

Component component = new ConcreteComponent(); // 创建被装饰对象
component.operation(); // 调用基础操作
 
Decorator decorator = new ConcreteDecorator(component); // 使用被装饰对象进行初始化
decorator.operation(); // 调用装饰器的操作方法,同时也会执行被装饰对象的操作方法和新添加的行为

在运行时,我们可以看到以下输出:

基础操作
基础操作
添加额外的行为

这表明操作被成功地传递到了被装饰者对象,并且具体的装饰器添加了额外的行为。

7、适配器模式(Adapter Pattern)

适配器模式(Adapter Pattern)是一种结构型设计模式,用于将一个已有类的接口转换成需要的接口形式。

适配器模式目的是让原本接口不兼容的类可以合作无间。在适配器模式中,适配器让一个类的接口与另一个类的接口相适应。

适配器的实现方法有两种:对象适配器和类适配器。

  • 对象适配器:适配器持有原始对象的引用,从而将其自己的接口与原始对象的接口“结合”在一起。
  • 类适配器:适配器通过多重继承实现将一个类的接口转换成另一个类所期望的接口形式。

以下是简单的适配器模式示例代码:

  • 对象适配器:

    // 原始接口
    interface Shape {
        void draw();
    }
    
    // 原始类
    class Rectangle implements Shape {
        public void draw() {
            System.out.println("Rectangle draw()");
        }
    }
    
    // 适配器类
    class ObjectAdapter implements Shape {
        private Rectangle rectangle;
    
        public ObjectAdapter(Rectangle rectangle) {
            this.rectangle = rectangle;
        }
    
        public void draw() {
            rectangle.draw();
        }
    }
    
    // 测试代码
    public class ObjectAdapterTest {
        public static void main(String[] args) {
            Rectangle rectangle = new Rectangle();
            Shape shape = new ObjectAdapter(rectangle);
            shape.draw();
        }
    }
    
  • 类适配器:

    // 原始类
    class Rectangle {
        void draw() {
            System.out.println("Rectangle draw()");
        }
    }
    
    // 目标接口
    interface Shape {
        void draw();
    }
    
    // 适配器类
    class ClassAdapter extends Rectangle implements Shape {
        public void draw() {
            super.draw();
        }
    }
    
    // 测试代码
    public class ClassAdapterTest {
        public static void main(String[] args) {
            Shape shape = new ClassAdapter();
            shape.draw();
        }
    }
    

在上面的代码中,我们有一个原始对象 Rectangle,它实现了 Shape 接口。在对象适配器模式中,我们创建了一个适配器 ObjectAdapter,以将该原始对象转换为 Shape 接口。在类适配器模式中,我们通过多重继承,将 Rectangle 类转换为 Shape 接口。在测试代码中,我们可以看到适配器的使用,将适配器对象传入客户端代码,并调用相应的方法。

总体来说,适配器模式是一种有效的设计模式,可以帮助我们处理接口不兼容的问题,从而使得不同的类可以相互协作完成任务。

8、观察者模式(Observer Pattern)

观察者模式(Observer Pattern)是一种行为型设计模式,也叫发布-订阅模式,它定义了对象之间一对多的依赖关系,使得当一个对象状态改变时,所有依赖它的对象都能收到通知并自动更新。

观察者模式中,有两种类型的对象:观察者和主题(或称为被观察者)。观察者将自己注册到主题,以便在主题的状态改变时接收通知。主题会维护一组观察者,并在自身状态改变时通知它们。主题通过调用观察者的统一接口来通知它们状态的变化。

以下是简单的观察者模式示例代码:

// 观察者接口
interface Observer {
    void update(String message);
}
 
// 具体观察者1
class ConcreteObserver1 implements Observer {
    @Override
    public void update(String message) {
        System.out.println("ConcreteObserver1:" + message);
    }
}
 
// 具体观察者2
class ConcreteObserver2 implements Observer {
    @Override
    public void update(String message) {
        System.out.println("ConcreteObserver2:" + message);
    }
}
 
// 主题接口
interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObserver(String message);
}
 
// 具体主题
class ConcreteSubject implements Subject {
    private List<Observer> list = new ArrayList<>();
 
    // 注册观察者
    public void registerObserver(Observer observer) {
        list.add(observer);
    }
 
    // 移除观察者
    public void removeObserver(Observer observer) {
        list.remove(observer);
    }
 
    // 通知观察者
    public void notifyObserver(String message) {
        for (Observer observer : list) {
            observer.update(message);
        }
    }
}

在上面的代码中,我们有观察者接口 Observer 和具体实现的两个观察者 ConcreteObserver1ConcreteObserver2。还有主题接口 Subject,它有三个方法:registerObserverremoveObservernotifyObserver,用于注册观察者、移除观察者和通知观察者。最后,我们有一个具体的主题 ConcreteSubject,它维护了 Observer 对象的列表,实现了 Subject 接口中的三个方法。

以下是使用Java观察者模式的示例代码:

public class ObserverTest {
    public static void main(String[] args) {
        ConcreteSubject subject = new ConcreteSubject(); // 创建具体主题
        Observer observer1 = new ConcreteObserver1(); // 创建具体观察者1
        Observer observer2 = new ConcreteObserver2(); // 创建具体观察者2
        subject.registerObserver(observer1); // 注册观察者1
        subject.registerObserver(observer2); // 注册观察者2
        subject.notifyObserver("观察者模式测试"); // 通知所有观察者
    }
}

在测试代码中,我们创建了一个具体主题 ConcreteSubject 和两个具体观察者 ConcreteObserver1ConcreteObserver2。它们的行为是在主题状态改变之后被调用。我们注册了这两个观察者,并用 notifyObserver() 方法通知它们主题状态已经改变。

在观察者模式中,主题和观察者的分离使代码具有更好的松耦合性,使得对象之间可以更加灵活地交互和协作。

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
扎眼的阳光的头像扎眼的阳光普通用户
上一篇 2023年12月11日
下一篇 2023年12月11日

相关推荐