Netty中的设计模式

文章中整理了部分设计模式,有些设计模式还没有吃透,所以暂且不提。

Netty设计模式应用

单例模式

  • 应用程序中的Singleton对象都使用Singleton类的同一实例
实现方式
  • 实现方式一
public class Singleton1 {

    public static final Singleton1 INSTANCE = new Singleton1();

    private Singleton1(){}

}
复制代码
  • 实现方式二
public class Singleton2_1 {

    private Singleton2_1() {}

    private static Singleton2_1 instance = null;

    public static Singleton2_1 getInstance() {
        if (null == instance) {
            instance = new Singleton2_1();
        }
        return instance;
    }

}
复制代码
public class Singleton2_2 {

    private Singleton2_2() {}

    private static Singleton2_2 instance = null;

    public static Singleton2_2 getInstance() {
        if (null == instance) {
            synchronized(Singleton2_2.class) {
                if (null == instance) {
                    instance = new Singleton2_2();
                }
            }
        }
        return instance;
    }

}
复制代码
public class Singleton2_3 {

    private Singleton2_3() {}

    // 防止指令重排
    private static volatile Singleton2_3 instance = null;

    public static Singleton2_3 getInstance() {
        if (null == instance) {
            synchronized(Singleton2_3.class) {
                if (null == instance) {
                    instance = new Singleton2_3();
                }
            }
        }
        return instance;
    }

}
复制代码
  • 实现方式三
public class Singleton3 {

    private Singleton3() {}

    public static Singleton3 getInstance() {
        return SingletonHolder.instance;
    }

    private static class SingletonHolder {
        private static final Singleton3 instance = new Singleton3();
    }

}
复制代码
  • 实现方式四
public enum Singleton4 {
    INSTANCE;
}
复制代码
Netty中的应用
  • ReadTimeoutException
public final class ReadTimeoutException extends TimeoutException {

    private static final long serialVersionUID = 169287984113283421L;

    public static final ReadTimeoutException INSTANCE = new ReadTimeoutException();

    private ReadTimeoutException() { }
}
复制代码
  • MqttEncoder
@ChannelHandler.Sharable
public final class MqttEncoder extends MessageToMessageEncoder<MqttMessage> {

    public static final MqttEncoder INSTANCE = new MqttEncoder();

    private MqttEncoder() { }

    //...省略代码
}
复制代码

策略模式

  • 对象都具有职责
  • 这些职责不同的具体实现是通过多态完成
  • 相同的算法具有多个不同的实现,需要进行管理
组成
  • 抽象策略角色:通常有一个接口或一个抽象类实现
  • 具体策略角色:包装了相关的算法和行为
  • 环境角色(也称上下文):持有一个策略类的应用,最终供客户端调用
实现方式
  • 抽象策略角色
public interface PubStrategy {
    void pub(String key);
}
复制代码
  • 具体策略角色
public class RolePubStrategy implements PubStrategy {

    @Override
    public void pub(String key) {
        // get users by role key
        System.out.println("1.Get users by role key...");
        // foreach pub msg to users
        System.out.println("2.Foreach pub msg to users...");
    }

}
复制代码
public class UserPubStrategy implements PubStrategy {

    @Override
    public void pub(String key) {
        // find user by key
        System.out.println("1.Get user by key...");
        // pub msg to user
        System.out.println("2.Pub msg to user...");
    }

}
复制代码
public class StrategyContext {

    private PubStrategy strategy;

    public StrategyContext(PubStrategy strategy) {
        this.strategy = strategy;
    }

    public void pub(String key) {
        strategy.pub(key);
    }

}
复制代码
Netty中的应用
  • 一个变种的策略模式应用EventExecutorChooserFactory#newChooser(EventExecutor[])
@UnstableApi
interface EventExecutorChooser {

    /**
        * Returns the new {@link EventExecutor} to use.
        */
    EventExecutor next();
}
复制代码
public final class DefaultEventExecutorChooserFactory implements EventExecutorChooserFactory {

    public static final DefaultEventExecutorChooserFactory INSTANCE = new DefaultEventExecutorChooserFactory();

    private DefaultEventExecutorChooserFactory() { }

    @SuppressWarnings("unchecked")
    @Override
    public EventExecutorChooser newChooser(EventExecutor[] executors) {
        if (isPowerOfTwo(executors.length)) {
            return new PowerOfTwoEventExecutorChooser(executors);
        } else {
            return new GenericEventExecutorChooser(executors);
        }
    }

    private static boolean isPowerOfTwo(int val) {
        return (val & -val) == val;
    }

    private static final class PowerOfTwoEventExecutorChooser implements EventExecutorChooser {
        private final AtomicInteger idx = new AtomicInteger();
        private final EventExecutor[] executors;

        PowerOfTwoEventExecutorChooser(EventExecutor[] executors) {
            this.executors = executors;
        }

        @Override
        public EventExecutor next() {
            return executors[idx.getAndIncrement() & executors.length - 1];
        }
    }

    private static final class GenericEventExecutorChooser implements EventExecutorChooser {
        private final AtomicInteger idx = new AtomicInteger();
        private final EventExecutor[] executors;

        GenericEventExecutorChooser(EventExecutor[] executors) {
            this.executors = executors;
        }

        @Override
        public EventExecutor next() {
            return executors[Math.abs(idx.getAndIncrement() % executors.length)];
        }
    }
}
复制代码

装饰者模式

  • 动态的给对象添加个职责
组成
  • 装饰接口
  • 装饰者
  • 被装饰者
实现方式

上面策略模式的StrategyContext修改成StrategyContextDecorator。

public class StrategyContextDecorator implements PubStrategy {
    
    private PubStrategy pubStrategy;
    
    public StrategyContextDecorator(PubStrategy pubStrategy) {
        this.pubStrategy = pubStrategy;
    }
    
    @Override
    public void pub(String key) {
        pubStrategy.pub(key);
    }
    
}
复制代码
Netty中的应用
class WrappedByteBuf extends ByteBuf {

    protected final ByteBuf buf;

    protected WrappedByteBuf(ByteBuf buf) {
        if (buf == null) {
            throw new NullPointerException("buf");
        }
        this.buf = buf;
    }

    @Override
    public final boolean hasMemoryAddress() {
        return buf.hasMemoryAddress();
    }

    // ...省略代码
}
复制代码

观察者模式

组成
  • 抽象主题(被观察的对象):
    • 主题是观察者观察的对象,一个主题必须具备下面三个特征:
      • 持有监听的观察者的引用
      • 支持增加和删除观察者
      • 主题状态改变,通知观察者
  • 观察者:
    • 当主题发生变化,收到通知进行具体的处理是观察者必须具备的特征。
  • 具体的抽象主题
  • 具体的观察者
实现方式
public abstract class Observerable {

    protected List<Observer> observers;
    protected String message;

    /**
     * 添加一个观察者
     * @param observer 观察者对象
     */
    abstract public void registerObserver(Observer observer);

    /**
     * 移除一个观察者
     * @param observer 观察者对象
     */
    abstract public void removeObserver(Observer observer);

    /**
     * 通知所有观察者
     */
    abstract public void notifyObserver(String message);

}
复制代码
public class ConcreteObserverable extends Observerable {

    public ConcreteObserverable() {
        observers = Lists.newArrayList();
    }

    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObserver(String message) {
        this.message = message;
        for (Observer observer: observers) {
            observer.update(message);
        }
    }

}
复制代码
public interface Observer {
    public void update(String message);
}
复制代码
public class ConcreteObserver implements Observer {

    @Override
    public void update(String message) {
        System.out.println("message up: " + message);
    }

}
复制代码
Netty中的应用
// 被观察对象
public interface ChannelFuture extends Future<Void> {

    Channel channel();

    // ...省略代码
    @Override
    ChannelFuture addListener(GenericFutureListener<? extends Future<? super Void>> listener);

    @Override
    ChannelFuture removeListener(GenericFutureListener<? extends Future<? super Void>> listener);
   
}
// 具体被观察对象
public class DefaultPromise<V> extends AbstractFuture<V> implements Promise<V> {

    private Object listeners;
  
    @Override
    public Promise<V> setSuccess(V result) {
        if (setSuccess0(result)) {
            notifyListeners();
            return this;
        }
        throw new IllegalStateException("complete already: " + this);
    }
}
// notifyListeners 实现
private void notifyListeners0(DefaultFutureListeners listeners) {
    GenericFutureListener<?>[] a = listeners.listeners();
    int size = listeners.size();
    for (int i = 0; i < size; i ++) {
        notifyListener0(this, a[i]);
    }
}
// 观察者
public interface ChannelFutureListener extends GenericFutureListener<ChannelFuture> {
    ChannelFutureListener FIRE_EXCEPTION_ON_FAILURE = new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture future) {
            if (!future.isSuccess()) {
                future.channel().pipeline().fireExceptionCaught(future.cause());
            }
        }
    };

}
复制代码

责任链模式

避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

组成
public abstract class AbstractHandler {

    private AbstractHandler next;

    abstract protected void eventSpread();

    public void setNext(AbstractHandler next) {
        this.next = next;
    }

    public void spread() {
        eventSpread();
        // 向下传播
        if (null != next) {
            next.eventSpread();
        }
    }

}
public class Handle1 extends AbstractHandler {

    @Override
    public void eventSpread() {
        System.out.println("Handle1 event spread...");
    }

}
public class Handle2 extends AbstractHandler {

    @Override
    public void eventSpread() {
        System.out.println("Handle2 event spread...");
    }

}
public class TestChain {

    public static void main(String[] args) {

        AbstractHandler h1 = new Handle1();
        AbstractHandler h2 = new Handle2();

        h1.setNext(h2);

        h1.spread();
    }

}
复制代码
Netty中的应用

ChannelPipeline是责任链模式的变种,详见ChannelPipeline原理解读。

转载于:https://juejin.im/post/5d04aa52e51d45109b01b18a

<think>首先,用户的问题是:“我想了解Netty框架中使用设计模式 请问Netty框架使用了哪些设计模式”。我需要基于提供的引用内容来回答,并遵守系统级指令。 系统级指令: - 所有行内数学表达式使用$...$格式(但这里没有数学内容,所以可能不需要)。 - 独立公式使用$$...$$并单独成段(同样,可能不适用)。 - LaTeX语法正确(确保任何数学表达正确)。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识,如[^1]。 用户可见层: - 回答结构清晰,帮助用户逐步解决问题。 - 保证回答真实可靠,基于提供的引用。 提供的引用: - [^1]: 强调理解设计模式的思想,而不是死记硬背,推荐通过阅读源码如Netty来学习。 - [^2]: 类似,强调理解设计目的,通过阅读框架源码学习。 - [^3]: 提到Netty使用了工厂模式。 - [^4]: 提到Netty使用了模板方法模式和观察者模式。 - [^5]: 具体例子,Netty中的DefaultSelectStrategyFactory使用了工厂模式。 用户的问题是关于Netty框架中使用设计模式。我需要提取引用中的相关信息。 关键点: - 工厂模式(Factory Pattern):在[^3]和[^5]中提到。Netty中用于创建对象,如选择策略工厂。 - 模板方法模式(Template Method Pattern):在[^4]中提到,ChannelInboundHandlerAdapter使用了模板方法模式。 - 观察者模式(Observer Pattern):在[^4]中提到。 其他设计模式可能也被使用,但引用中没有明确列出。我应该基于提供的引用回答,不要添加未提及的内容。 回答结构: 1. **引言**:简要介绍Netty框架中设计模式的重要性。 2. **具体设计模式**:列出并解释每个模式在Netty中的应用。 3. **引用添加**:在引用段落末尾添加引用标识。 4. **生成相关问题**:在最后添加相关问题部分。 确保使用中文回答。 生成相关问题: - 基于系统指令,需要生成相关问题。例如: - Netty中工厂模式的具体实现是怎样的? - 模板方法模式在Netty中如何应用? - 还有其他设计模式Netty使用吗? 完整回答: - 先回答用户问题。 - 然后添加相关问题。 最终输出格式: - 回答部分。 - §§相关问题§§部分。</think>### Netty框架中使用设计模式 Netty 是一个高性能、异步事件驱动的网络应用框架,广泛用于构建服务器和客户端。在 Netty 的设计中,设计模式被巧妙地应用,以提高代码的可扩展性、可维护性和灵活性。以下基于引用内容,总结 Netty 中主要使用设计模式及其应用场景。设计模式的学习应注重理解其思想,而非死记硬背,通过阅读源码(如 Netty)能有效提升代码设计能力[^1][^2]。 #### 1. **工厂模式(Factory Pattern)** - **定义**:工厂模式是一种创建型设计模式,它定义一个用于创建对象的接口,但将实例化的过程延迟到子类或具体实现类中,从而隐藏对象的创建细节[^3]。 - **在 Netty 中的应用**:Netty 使用工厂模式来创建策略对象或处理器实例。例如,在事件循环组(EventLoopGroup)中,`DefaultSelectStrategyFactory` 负责创建选择策略对象(SelectStrategy)。这确保了策略的创建过程被封装,便于扩展和替换实现[^5]。 - 示例代码片段(基于引用): ```java public final class DefaultSelectStrategyFactory implements SelectStrategyFactory { public static final SelectStrategyFactory INSTANCE = new DefaultSelectStrategyFactory(); private DefaultSelectStrategyFactory() { } @Override public SelectStrategy newSelectStrategy() { return DefaultSelectStrategy.INSTANCE; // 延迟创建策略对象 } } ``` - **优势**:提高了代码的灵活性和解耦,允许在不修改客户端代码的情况下更换策略实现[^3][^5]。 #### 2. **模板方法模式(Template Method Pattern)** - **定义**:模板方法模式是一种行为型设计模式,它定义一个算法骨架,将某些步骤延迟到子类实现,从而复用公共逻辑[^4]。 - **在 Netty 中的应用**:Netty 的处理器(Handler)设计中广泛使用此模式。例如,`ChannelInboundHandlerAdapter` 类定义了一个模板方法 `channelRead`,其中包含公共逻辑(如解码),而具体处理步骤(如业务逻辑)由子类通过抽象方法 `onChannelRead` 实现[^4]。 - 示例代码片段(基于引用): ```java public abstract class ChannelInboundHandlerAdapter extends ChannelHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { // 公共逻辑(如解码) onChannelRead(ctx, msg); // 调用子类实现的具体步骤 } protected abstract void onChannelRead(ChannelHandlerContext ctx, Object msg); } ``` - **优势**:简化了处理器开发,子类只需关注特定步骤,而公共逻辑(如错误处理)在父类中统一维护[^4]。 #### 3. **观察者模式(Observer Pattern)** - **定义**:观察者模式是一种行为型设计模式,它定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会自动收到通知并更新[^4]。 - **在 Netty 中的应用**:Netty 的事件驱动模型核心就是观察者模式。例如,`ChannelPipeline` 中的处理器(Handler)作为观察者,监听事件(如数据到达或连接关闭)。当事件发生时,`ChannelHandlerContext` 会通知所有注册的处理器,实现异步事件处理[^4]。 - **优势**:支持高并发和事件驱动架构,处理器可以动态添加或移除,增强了框架的扩展性[^4]。 ### 总结 Netty 框架通过上述设计模式(工厂模式、模板方法模式、观察者模式)实现了模块化、可扩展和高性能。这些模式的应用不仅提升了代码质量,还体现设计模式的核心思想:解决特定问题(如对象创建、算法复用、事件通知)而非炫技[^2]。学习 Netty 源码是掌握设计模式的有效途径,建议结合实际项目或阅读 Spring、MyBatis 等框架源码加深理解[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值