常用设计模式
基本设计原则
- 七种设计原则
- 开闭原则 对扩展开放,对修改关闭。
- 依赖倒置原则 抽象不应该依赖细节,细节应该依赖抽象。
- 接口隔离原则 一个类对另一个类的依赖应该建立在最小的接口上。
- 迪米特法则 迪米特法则又叫最少知识原则。如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。
- 里氏替换原则 任何基类可以出现的地方,子类一定可以出现。子类可以扩展父类的功能,但不能改变父类原有的功能。
- 合成复用原则 合成复用原则是指:尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。
面向对象编程 (Object-Oriented Programming, OOP):使用对象、类和继承等概念来组织和管理代码,以实现抽象、封装和多态。
分层架构 (Layered Architecture):将系统划分为不同层次,每一层负责特定的功能,有助于提高系统的可维护性和扩展性。
解耦 (Decoupling):减少模块之间的依赖,以降低系统复杂性,并使组件更容易替换或重用。
分治思想 (Divide and Conquer):将问题分解成较小的子问题,分别解决每个子问题,然后将它们的解决方案组合成原问题的解决方案。
开闭原则 (Open-Closed Principle, OCP):软件实体(类、模块、函数等)应该对扩展开放,对修改关闭,以便通过添加新功能来扩展系统,而不需修改现有代码。
单一职责原则 (Single Responsibility Principle, SRP):一个模块(类、方法等)应该只有一个引起变化的原因,即每个模块应该有单一的职责。
依赖倒转原则 (Dependency Inversion Principle, DIP):高层模块不应该依赖于低层模块,两者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。
接口隔离原则 (Interface Segregation Principle, ISP):客户端不应该被强制依赖它不使用的接口。一个类不应该被迫实现它不需要的接口。
组合优于继承 (Composition Over Inheritance):尽量使用组合(包含其他对象)而不是继承(从其他类派生)来重用和扩展功能。
模块化 (Modularity):将系统划分成小模块,每个模块都有明确定义的接口,有助于代码的组织、测试和维护。
建造者模式(Builder Pattern)
建造者模式是一种创建型设计模式,其核心思想是将一个复杂对象的构建过程与其表示分离,使同样的构建过程可以创建不同的表示。它允许你构建一个复杂对象的步骤,然后可以根据需要选择不同的表示方式。
逻辑过程:
建造者模式通常包括以下主要参与者:
Director(指导者):指导者负责指导建造者构建对象的具体步骤,通常不涉及具体产品的信息。
Builder(建造者):建造者接口定义了构建复杂对象的方法,这些方法通常包括一系列用于设置对象属性的方法。
ConcreteBuilder(具体建造者):具体建造者实现了建造者接口,负责实际构建对象的各个部分,并提供方法来获取构建后的对象。
Product(产品):产品是构建过程的结果,它包含了构建后的对象的属性。
逻辑过程如下:
- Director 创建一个 Builder 实例,通常通过构造函数传入。
- Director 使用 Builder 的方法来构建对象,按照一定的步骤和逻辑。
- 最终,Director 调用 Builder 的一个方法来获取构建好的对象。
// 产品类
class Product {
private String part1;
private String part2;
public void setPart1(String part1) {
this.part1 = part1;
}
public void setPart2(String part2) {
this.part2 = part2;
}
public void show() {
System.out.println("Part 1: " + part1);
System.out.println("Part 2: " + part2);
}
}
// 建造者接口
interface Builder {
void buildPart1();
void buildPart2();
Product getResult();
}
// 具体建造者
class ConcreteBuilder implements Builder {
private Product product = new Product();
@Override
public void buildPart1() {
product.setPart1("Part 1");
}
@Override
public void buildPart2() {
product.setPart2("Part 2");
}
@Override
public Product getResult() {
return product;
}
}
// 指导者
class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public void construct() {
builder.buildPart1();
builder.buildPart2();
}
}
public class BuilderPatternDemo {
public static void main(String[] args) {
Builder builder = new ConcreteBuilder();
Director director = new Director(builder);
director.construct();
Product product = builder.getResult();
product.show();
}
}
在上述示例中,Product 是要构建的复杂对象,Builder 是建造者接口,ConcreteBuilder 是具体建造者,Director 是指导者。通过指导者的构建过程,可以创建一个具有两个部分的 Product 对象。这允许你以相同的构建过程创建不同的产品表示。
抽象工厂模式 (Abstract Factory Pattern)
核心思想:
抽象工厂模式是一种创建型设计模式,其核心思想是提供一个接口用于创建一系列相关或依赖对象,而无需指定其具体类。抽象工厂允许客户端代码使用抽象接口来创建一组相关的对象,而不需要知道每个具体对象的类。
逻辑过程:
抽象工厂模式通常包括以下主要参与者:
Abstract Factory(抽象工厂):抽象工厂定义了一组用于创建一系列相关对象的方法,通常每个方法对应一个产品。
Concrete Factory(具体工厂):具体工厂是抽象工厂的实现,它实现了抽象工厂中定义的方法,用于创建具体的产品。
Abstract Product(抽象产品):抽象产品定义了一组通用的接口,通常包括一组操作,具体产品必须实现这些接口。
Concrete Product(具体产品):具体产品是由具体工厂创建的对象,它实现了抽象产品定义的接口。
逻辑过程如下:
客户端代码通过抽象工厂接口创建一个具体工厂对象。
具体工厂对象负责创建一组相关的具体产品对象。
客户端代码使用抽象产品接口来操作这些产品,而无需关心具体产品的类。
// Abstract Factory
interface UIFactory {
Button createButton();
Checkbox createCheckbox();
}
// Concrete Factories
class WindowsFactory implements UIFactory {
public Button createButton() {
return new WindowsButton();
}
public Checkbox createCheckbox() {
return new WindowsCheckbox();
}
}
class MacFactory implements UIFactory {
public Button createButton() {
return new MacButton();
}
public Checkbox createCheckbox() {
return new MacCheckbox();
}
}
// Abstract Products
interface Button {
void render();
}
interface Checkbox {
void render();
}
// Concrete Products
class WindowsButton implements Button {
public void render() {
System.out.println("Render a Windows button");
}
}
class MacButton implements Button {
public void render() {
System.out.println("Render a Mac button");
}
}
class WindowsCheckbox implements Checkbox {
public void render() {
System.out.println("Render a Windows checkbox");
}
}
class MacCheckbox implements Checkbox {
public void render() {
System.out.println("Render a Mac checkbox");
}
}
// Usage
UIFactory factory = new WindowsFactory(); // or MacFactory
Button button = factory.createButton();
button.render();
Checkbox checkbox = factory.createCheckbox();
checkbox.render();
原型模式 (Prototype Pattern)
原型模式(Prototype Pattern) 是一种创建型设计模式,它允许通过复制现有对象来创建新对象,而无需了解对象的具体类。该模式通常用于创建具有相同属性的对象,但需要避免构造函数和初始化步骤的开销。
核心思想:
原型模式的核心思想是基于已有的对象创建新的对象,即通过克隆(复制)一个现有对象来创建新对象。这个克隆的过程可以是浅克隆或深克隆,具体取决于需求。原型模式可以提高对象创建的性能,尤其在对象的初始化过程较为复杂或昂贵的情况下,因为它避免了重复的初始化步骤。
逻辑过程:
原型模式通常包括以下主要参与者:
Prototype(原型接口):定义了克隆自身的方法。
ConcretePrototype(具体原型):实现了原型接口,提供了克隆方法的具体实现。
Client(客户端):客户端代码使用原型对象来创建新对象,而不需要了解具体类。
逻辑过程如下:
客户端代码通过原型接口请求克隆(复制)一个已有对象,获得一个新的对象。
具体原型对象实现了克隆方法,将自身复制一份并返回给客户端。
客户端可以在需要时克隆多个对象,而无需重复初始化或构造。
// 原型接口
interface Prototype {
Prototype clone();
}
// 具体原型
class ConcretePrototype implements Prototype {
private int value;
public ConcretePrototype(int value) {
this.value = value;
}
@Override
public Prototype clone() {
// 创建一个新对象并将当前对象的状态复制给新对象
return new ConcretePrototype(this.value);
}
public int getValue() {
return value;
}
}
public class PrototypePatternDemo {
public static void main(String[] args) {
// 创建具体原型对象
Prototype prototype = new ConcretePrototype(10);
// 克隆原型对象
Prototype clone1 = prototype.clone();
Prototype clone2 = prototype.clone();
// 打印克隆后的对象的值
System.out.println("Clone 1 Value: " + ((ConcretePrototype) clone1).getValue());
System.out.println("Clone 2 Value: " + ((ConcretePrototype) clone2).getValue());
}
}
在上述示例中,ConcretePrototype 实现了 Prototype 接口,并提供了 clone 方法,它允许创建一个新的对象,该对象与原对象具有相同的值。客户端代码使用原型对象来创建新对象,而不需要知道具体的类。这种方式可以用来避免对象初始化开销,特别是当对象初始化复杂时。
装饰器模式 (Decorator Pattern)
装饰器模式(Decorator Pattern)和原型模式(Prototype Pattern)是两种不同的设计模式,它们解决不同类型的问题,没有直接的关联。让我先为你解释装饰器模式,然后再讨论原型模式。
装饰器模式 (Decorator Pattern)
核心思想: 装饰器模式允许你通过将对象放入包装对象中来动态地扩展其功能。这种模式适用于需要扩展对象功能而不影响其类结构的情况,从而使其更加灵活和可复用。
逻辑过程:
装饰器模式包括以下主要参与者:
Component(组件接口):定义了需要被装饰的对象的接口。
ConcreteComponent(具体组件):实现了组件接口,是被装饰的对象。
Decorator(装饰器抽象类):继承了组件接口,包含一个组件对象,同时定义了需要扩展的功能。
ConcreteDecorator(具体装饰器):继承了装饰器抽象类,实现了具体的功能扩展,可以包装具体组件或其他具体装饰器。
逻辑过程如下:
客户端创建一个具体组件对象,然后可以通过创建不同的具体装饰器对象来扩展该组件的功能。
每个装饰器包含一个组件对象,可以通过组合多个装饰器来叠加多个功能扩展。
/**
*
* * 装饰者模式(Decorator Pattern):属于结构型设计模式,它关注对象功能的扩展和组合。
* 装饰者模式(Decorator Pattern)是一种结构型设计模式,
* 它允许动态地给对象添加额外的职责,同时又不改变其接口。
* 装饰者模式通过将对象包装在装饰者类中,
* 以透明且递归的方式,为对象添加新的行为或功能。
*
* 抽象组件(Component):定义了被装饰者和装饰者的共同接口,可以是抽象类或接口。
* 具体组件(Concrete Component):实现了抽象组件的具体对象,被装饰者。
* 抽象装饰者(Decorator):继承自抽象组件,并持有一个抽象组件的引用。
* 它可以通过在调用抽象组件的方法前后添加额外的行为,来扩展被装饰者的功能。
* 具体装饰者(Concrete Decorator):继承自抽象装饰者,并实现了具体的装饰逻辑。
* 它可以在装饰者的基础上添加自己特定的行为。
*
* 总结来说,装饰者模式允许通过组合和递归的方式,动态地为对象添加新的行为或功能,而不改变其接口。
* 它是一种灵活且可扩展的设计模式,能够提供代码的复用性和可维护性。
*/
// 组件接口
interface Coffee {
double cost();
}
// 具体组件
class SimpleCoffee implements Coffee {
@Override
public double cost() {
return 2.0;
}
}
// 装饰器抽象类
abstract class CoffeeDecorator implements Coffee {
private final Coffee decoratedCoffee;
public CoffeeDecorator(Coffee coffee) {
this.decoratedCoffee = coffee;
}
@Override
public double cost() {
return decoratedCoffee.cost();
}
}
// 具体装饰器
class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public double cost() {
return super.cost() + 1.0;
}
}
class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee coffee) {
super(coffee);
}
@Override
public double cost() {
return super.cost() + 0.5;
}
}
public class DecoratorPatternDemo {
public static void main(String[] args) {
// 创建一个简单咖啡
Coffee coffee = new SimpleCoffee();
System.out.println("Cost: $" + coffee.cost());
// 添加牛奶
coffee = new MilkDecorator(coffee);
System.out.println("Cost: $" + coffee.cost());
// 再添加糖
coffee = new SugarDecorator(coffee);
System.out.println("Cost: $" + coffee.cost());
}
}
在上述示例中,Coffee 是组件接口,SimpleCoffee 是具体组件。CoffeeDecorator 是装饰器抽象类,它包含了一个 decoratedCoffee 对象,并实现了 cost 方法。MilkDecorator 和 SugarDecorator 是具体装饰器,它们扩展了咖啡的功能,可以叠加使用。
观察者模式 (Observer Pattern)
观察者模式(Observer Pattern)是一种行为设计模式,它定义了对象之间的一对多依赖关系,以便当一个对象状态改变时,所有依赖它的对象都会得到通知并自动更新。这个模式被广泛应用于各种编程场景,包括图形用户界面(GUI)、事件处理系统、发布-订阅系统等。
核心思想: 观察者模式的核心思想是,一个主题对象(被观察者)维护一组观察者,当主题对象的状态发生改变时,它会通知所有观察者,使它们能够自动更新。这种松散耦合的设计模式允许对象之间的交互变得更加灵活和可维护。
关键参与者:
Subject(主题):定义了被观察的对象接口。主题对象可以有多个观察者,它维护一个观察者列表,提供方法用于添加、删除和通知观察者。
ConcreteSubject(具体主题):实现主题接口,维护主题的状态,当状态发生变化时通知观察者。
Observer(观察者):定义了一个更新接口,用于观察者接收主题状态变化的通知。
ConcreteObserver(具体观察者):实现观察者接口,接收主题的通知,并根据通知更新自己的状态。
逻辑过程:
逻辑过程如下:
主题对象(被观察者)维护一个观察者列表。
观察者将自己注册到主题对象的观察者列表中。
主题对象的状态发生变化时,它会遍历观察者列表,调用每个观察者的更新方法,通知它们状态的改变。
观察者接收到通知后,执行自己的更新逻辑。
import java.util.ArrayList;
import java.util.List;
// 主题接口
interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
// 具体主题
class ConcreteSubject implements Subject {
private int state;
private List<Observer> observers = new ArrayList<>();
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(state);
}
}
public void setState(int state) {
this.state = state;
notifyObservers();
}
}
// 观察者接口
interface Observer {
void update(int state);
}
// 具体观察者
class ConcreteObserver implements Observer {
private int observerState;
@Override
public void update(int state) {
observerState = state;
System.out.println("Observer updated with state: " + observerState);
}
}
public class ObserverPatternDemo {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
ConcreteObserver observer1 = new ConcreteObserver();
ConcreteObserver observer2 = new ConcreteObserver();
subject.registerObserver(observer1);
subject.registerObserver(observer2);
subject.setState(10);
subject.removeObserver(observer1);
subject.setState(20);
}
}
在上述示例中,ConcreteSubject 是具体主题,维护了一个状态和一个观察者列表。ConcreteObserver 是具体观察者,实现了观察者接口的 update 方法。当主题状态发生变化时,它会通知所有注册的观察者,观察者会更新自己的状态。观察者模式实现了松散耦合的通信机制,允许主题和观察者之间的独立演化。
策略模式 (Strategy Pattern)
策略模式(Strategy Pattern)是一种行为设计模式,它允许定义一系列算法,将每个算法封装起来,并使它们可以互相替换。策略模式使得算法可以独立于客户端而变化,客户端可以在运行时选择合适的算法来使用。
核心思想: 策略模式的核心思想是将算法的定义、选择和使用分开,使得算法可以独立于客户端进行变化。它通过定义一组算法,封装每个算法为一个策略对象,使客户端能够选择并切换不同的策略。
关键参与者:
Context(上下文):维护一个对策略对象的引用,可以动态地改变策略。
Strategy(策略):定义了所有支持的算法的公共接口,具体策略类实现了这个接口。
ConcreteStrategy(具体策略):实现了策略接口,提供具体的算法实现。
逻辑过程:
上下文对象持有一个策略接口的引用,根据客户端的要求选择合适的策略。
客户端通过上下文对象使用策略,无需关心策略的具体实现细节。
可以在运行时动态改变策略,而客户端代码无需修改。
实际上就是将原有的if、else,并基于开闭原则进行优化
import java.util.HashMap;
import java.util.Map;
public class SalaryCalculator {
private static final int HIGH_RATE = 25;
private static final int MIDDLE_RATE = 20;
private static final int LOW_RATE = 15;
private static final Map<String, Integer> rates = new HashMap<>();
static {
rates.put("high", HIGH_RATE);
rates.put("middle", MIDDLE_RATE);
rates.put("low", LOW_RATE);
}
public static int calculateSalary(String workerLevel, int workHours) {
int rate = rates.getOrDefault(workerLevel, 0);
if (rate == 0) {
throw new IllegalArgumentException("Invalid worker level: " + workerLevel);
}
return workHours * rate;
}
public static void main(String[] args) {
System.out.println(calculateSalary("high")); // Output: 250
System.out.println(calculateSalary("middle")); // Output: 200
}
}
// 策略接口
interface PaymentStrategy {
void pay(int amount);
}
// 具体策略 - 现金支付
class CashPayment implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println("Paid " + amount + " using cash.");
}
}
// 具体策略 - 信用卡支付
class CreditCardPayment implements PaymentStrategy {
private String cardNumber;
public CreditCardPayment(String cardNumber) {
this.cardNumber = cardNumber;
}
@Override
public void pay(int amount) {
System.out.println("Paid " + amount + " using credit card with number " + cardNumber);
}
}
// 上下文
class ShoppingCart {
private PaymentStrategy paymentStrategy;
public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
public void checkout(int amount) {
paymentStrategy.pay(amount);
}
}
public class StrategyPatternDemo {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();
// 使用现金支付
cart.setPaymentStrategy(new CashPayment());
cart.checkout(100);
// 使用信用卡支付
cart.setPaymentStrategy(new CreditCardPayment("1234-5678-9876-5432"));
cart.checkout(200);
}
}
在上述示例中,我们定义了两种支付策略:CashPayment 和 CreditCardPayment,它们都实现了 PaymentStrategy 接口。ShoppingCart 上下文对象可以在运行时选择使用哪种支付策略,而客户端代码无需修改。这展示了策略模式的灵活性和可扩展性。
适配器模式 (Adapter Pattern)
/** 适配器模式(Adapter Pattern):属于结构型设计模式,它关注对象之间的接口转换和兼容性。
*
* 适配器模式,它的功能是将一个类的接口变成客户端所期望的另一种接口,
* 从而使原本因接口不匹配而导致无法在一起工作的两个类能够一起工作。
* 适配器模式分为类适配器模式和对象适配器模式,前者类之间的耦合度比后者高,
* 且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。
*
* 目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。
* 适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。
* 适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。
*
*/
interface SD{
void getInfo();
}
interface TD{
void getTDInfo();
}
class real_sd implements SD{
@Override
public void getInfo() {
System.out.println("SD获取数据");
}
}
class real_td implements TD{
@Override
public void getTDInfo() {
System.out.println("TD获取数据");
}
}
class computer{
void getInfo(SD sd){
sd.getInfo();
}
}
/**
* 类适配器
* */
/*class adapter implements SD,TD{
@Override
public void getInfo() {
System.out.println("适配器td->sd");
getTDInfo();
}
@Override
public void getTDInfo() {
System.out.println("TD获取数据");
}
}*/
/**
* 对象适配器
* */
class adapter implements SD{
private TD td;
public adapter(TD td){
this.td = td;
}
@Override
public void getInfo() {
System.out.println("适配器td->sd");
td.getTDInfo();
}
}
class testAdapter{
public static void main(String[] args) {
computer computer = new computer();
computer.getInfo(new real_sd());
computer.getInfo(new adapter(new real_td()));
}
}
代理模式(Proxy Pattern)
代理模式(Proxy Pattern)是一种结构型设计模式,用于创建一个代理对象,以控制对其他对象的访问。代理通常充当客户端和真实对象之间的中介,以添加额外的控制或管理功能。
核心思想: 代理模式的核心思想是通过引入一个代理对象,来控制客户端对真实对象的访问。代理对象拥有与真实对象相同的接口,使客户端能够无需了解真实对象的具体实现细节。
关键参与者:
Subject(主题):定义了真实对象和代理对象的共同接口,客户端通过这个接口访问真实对象。
RealSubject(真实主题):实际执行工作的类,客户端希望通过代理来访问这个对象。
Proxy(代理):充当客户端和真实对象之间的中介,它实现了与主题相同的接口。代理对象可以对真实对象的访问进行控制,例如延迟加载、权限验证、缓存等。
逻辑过程:
客户端通过代理对象来访问真实对象。
代理对象可以在访问真实对象之前或之后执行一些额外的操作,如权限检查、记录日志、延迟加载等。
/**
* 结构型模式
*
* 代理模式
* 静态代理/动态
* 抽象主题
* 真实主题
* 代理类
*
*/
// 定义接口
interface Subject1 {
void doSomething();
}
// 实现接口的具体类
class RealSubject implements Subject1 {
@Override
public void doSomething() {
System.out.println("RealSubject is doing something.");
}
}
// 实现InvocationHandler接口创建动态代理类
class ProxyHandler implements InvocationHandler {
private Object target;
public ProxyHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before method invocation.");
Object result = method.invoke(target, args);
System.out.println("After method invocation.");
return result;
}
}
// 测试代码
class Main12344 {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
ProxyHandler proxyHandler = new ProxyHandler(realSubject);
// 创建动态代理对象
Subject1 proxySubject = (Subject1) Proxy.newProxyInstance(
realSubject.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(),
proxyHandler
);
// 通过动态代理对象调用方法
proxySubject.doSomething();
}
}
模板方法模式 (Template Method Pattern)
模板方法模式是一种行为设计模式,它定义了一个算法的框架,但将一些步骤的具体实现延迟到子类。这个模式允许子类重新定义算法的某些步骤,而不改变算法的结构。
在模板方法模式中,通常有一个抽象类,该类包含一个模板方法,这个模板方法定义了算法的基本结构,并包含一些抽象方法或者可被子类重写的方法。具体子类通过实现这些方法来定制化算法的不同部分。
// 抽象类定义了算法的框架
abstract class AlgorithmTemplate {
public void execute() {
initialize();
doProcessing();
finalize();
}
// 抽象方法,由子类来实现
protected abstract void initialize();
protected abstract void doProcessing();
protected abstract void finalize();
}
// 具体子类实现抽象方法
class ConcreteAlgorithmA extends AlgorithmTemplate {
@Override
protected void initialize() {
System.out.println("Initialize Algorithm A");
}
@Override
protected void doProcessing() {
System.out.println("Processing with Algorithm A");
}
@Override
protected void finalize() {
System.out.println("Finalize Algorithm A");
}
}
class ConcreteAlgorithmB extends AlgorithmTemplate {
@Override
protected void initialize() {
System.out.println("Initialize Algorithm B");
}
@Override
protected void doProcessing() {
System.out.println("Processing with Algorithm B");
}
@Override
protected void finalize() {
System.out.println("Finalize Algorithm B");
}
}
public class TemplateMethodPatternExample {
public static void main(String[] args) {
AlgorithmTemplate algorithmA = new ConcreteAlgorithmA();
AlgorithmTemplate algorithmB = new ConcreteAlgorithmB();
algorithmA.execute();
algorithmB.execute();
}
}
在上述示例中,AlgorithmTemplate 是一个抽象类,它定义了算法的模板方法 execute() 和抽象方法 initialize(), doProcessing(), 和 finalize()。两个具体的子类 ConcreteAlgorithmA 和 ConcreteAlgorithmB 分别实现了这些抽象方法以定义自己的行为。在 main 方法中,我们创建了两个不同的算法对象并调用它们的 execute() 方法,它们按照模板方法的结构执行。
这个模式的主要优点是将通用算法的骨架与具体实现分开,允许更容易扩展和修改算法,同时避免了代码的重复。
迭代器模式(Iterator Pattern)
迭代器模式(Iterator Pattern)是一种行为型设计模式,用于提供一种方法来访问一个聚合对象中的各个元素,而不需要暴露该对象的内部表示。迭代器模式将遍历元素和实际元素分离,使得你可以在不影响聚合对象的情况下遍历元素。
核心思想: 迭代器模式的核心思想是封装集合对象的遍历过程,使客户端能够迭代集合中的元素,而不需要了解集合的内部结构。迭代器模式提供了一种标准的方式来遍历各种不同类型的集合。
关键参与者:
Iterator(迭代器):定义了访问和遍历元素的接口,包括 hasNext() 用于检查是否还有下一个元素,next() 用于获取下一个元素。
ConcreteIterator(具体迭代器):实现了迭代器接口的具体类,负责追踪集合的当前位置,并实现遍历操作。
Aggregate(聚合):定义了创建迭代器对象的接口,通常包括一个 createIterator() 方法。
ConcreteAggregate(具体聚合):实现了聚合接口的具体类,负责创建对应的迭代器。
逻辑过程:
客户端通过聚合对象获取迭代器,然后使用迭代器遍历集合中的元素。
import java.util.ArrayList;
import java.util.List;
// 迭代器接口
interface Iterator {
boolean hasNext();
Object next();
}
// 具体迭代器
class ConcreteIterator implements Iterator {
private List<Object> elements;
private int position = 0;
public ConcreteIterator(List<Object> elements) {
this.elements = elements;
}
public boolean hasNext() {
return position < elements.size();
}
public Object next() {
if (hasNext()) {
Object element = elements.get(position);
position++;
return element;
}
return null;
}
}
// 聚合接口
interface Aggregate {
Iterator createIterator();
}
// 具体聚合
class ConcreteAggregate implements Aggregate {
private List<Object> elements = new ArrayList<>();
public void add(Object element) {
elements.add(element);
}
public Iterator createIterator() {
return new ConcreteIterator(elements);
}
}
public class IteratorPatternDemo {
public static void main(String[] args) {
ConcreteAggregate aggregate = new ConcreteAggregate();
aggregate.add("Element 1");
aggregate.add("Element 2");
aggregate.add("Element 3");
Iterator iterator = aggregate.createIterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
在这个示例中,Iterator 是迭代器接口,ConcreteIterator 是具体迭代器。Aggregate 是聚合接口,ConcreteAggregate 是具体聚合。客户端通过聚合对象创建迭代器,然后使用迭代器遍历聚合中的元素。迭代器模式可以用于各种集合类型,使客户端能够统一遍历它们,而不需要了解集合的内部结构。
单例模式 (Singleton Pattern)
单例模式(Singleton Pattern)是一种创建型设计模式,其主要目的是确保一个类只有一个实例,并提供一个全局访问点以访问该实例。这可以防止多个对象同时创建相同类的实例,确保全局的唯一性。
核心思想: 单例模式的核心思想是限制类的实例化过程,确保一个类只有一个实例存在。通常,单例模式包括以下几个要点:
私有构造函数: 类的构造函数必须是私有的,以防止外部直接创建实例。
私有静态成员变量: 类内部维护一个私有静态成员变量,用于保存唯一实例。
公共静态方法: 类提供一个公共的静态方法,用于获取唯一实例。在该方法内部,会检查是否已经存在实例,如果存在则返回已有实例,否则创建一个新实例并返回。
应用场景: 单例模式适用于那些需要严格控制唯一实例的情况,例如配置管理、数据库连接池、线程池等。
public class CreatorPattern {
//HungryMan
private static CreatorPattern creatorPattern = new CreatorPattern();
private CreatorPattern(){
}
public static CreatorPattern getSingle(){
return creatorPattern;
}
}
class CreatorPatternDemo1 {
private int id;
private String name;
//HungryMan
private static CreatorPatternDemo1 creatorPattern = new CreatorPatternDemo1();
public CreatorPatternDemo1(){
}
public CreatorPatternDemo1(int id, String name) {
this.id = id;
this.name = name;
}
public static CreatorPatternDemo1 getSingle(){
return creatorPattern;
}
}
class CreatorPatternLazy {
private int id;
private String name;
//lazyMan-safe
private static CreatorPatternLazy creatorPattern;
private CreatorPatternLazy(){
}
private CreatorPatternLazy(int id, String name) {
this.id = id;
this.name = name;
}
public static CreatorPatternLazy getSingleWithPamater(int id, String name){
if(creatorPattern == null){
creatorPattern = new CreatorPatternLazy(id, name);
}
return creatorPattern;
}
public static synchronized CreatorPatternLazy getSingle(){
if(creatorPattern == null){
creatorPattern = new CreatorPatternLazy();
}
return creatorPattern;
}
}
/**
* @Version :
* @ClassName:
* @Description:
* @Author:
* @CreateTime:
*/
class CreatorPatternLazyWithDoubleLock {
//lazyMan-safe
private static volatile CreatorPatternLazyWithDoubleLock creatorPattern; //volatile去解决指令重排序问题:java并发逻辑问题
private CreatorPatternLazyWithDoubleLock(){
}
public static CreatorPatternLazyWithDoubleLock getSingle(){
if(creatorPattern == null){
synchronized (CreatorPatternLazyWithDoubleLock.class){
if(creatorPattern == null){
creatorPattern = new CreatorPatternLazyWithDoubleLock();
}
}
}
return creatorPattern;
}
}