1.观察者模式

  有两个角色,观察者和被观察者。当被观察者发出消息后,注册了的观察者会收到其消息,而没有注册的观察者就不会收到。

//定义观察者接口
interface Observer{
//通知观察者
void notify(String message);
} //定义被观察者
interface Observed{
//注册观察者
void registerObserver(Observer o);
//移除观察者
void removeObserver(Observer o);
//通知观察者
void notifyObserver();
} //实现一个被观察者(女神)
class Gril implements Observed{
//女神最近的消息
private String message;
//追求女神的人
List<Observer> observerList; public Gril(){
observerList=new ArrayList<>();
} @Override
public void registerObserver(Observer o) {
//多了一位追求者
observerList.add(o);
} @Override
public void removeObserver(Observer o) {
//一位勇士放弃了
observerList.remove(o);
} @Override
public void notifyObserver() {
//女神发出了一点消息
for(Observer o:observerList){
o.notify(message);
}
} public void setMeesage(String message){
this.message=message;
}
} //实现观察者
class Handsome_Boy implements Observer{
@Override
public void notify(String message) {
System.out.println("隔壁班帅哥收到消息:"+message);
}
}
class Lao_Wang implements Observer{
@Override
public void notify(String message) {
System.out.println("老王收到消息:"+message);
}
}
class Gay implements Observer{
@Override
public void notify(String message) {
System.out.println("小伙汁收到消息:"+message);
}
}
//测试使用
public class observer_test {
public static void main(String[] args) {
//首先创建几个观察者和被观察者
Gril gril=new Gril();
Handsome_Boy boy=new Handsome_Boy();
Gay gay=new Gay();
Lao_Wang wang=new Lao_Wang(); //注册观察者
gril.registerObserver(boy);
gril.registerObserver(wang); //被观察者发出通知
gril.setMeesage("我好无聊啊");
gril.notifyObserver();
}
}

  Netty中的应用:NioSocketChannel.writeAndFlush()。

2.责任链模式

  责任链模式,让多个对象都有可能处理同一个请求,把多个对象连成一条链,让事件在这条链上传播,并且链上每个节点都可以终止传播 。熟悉Netty的朋友一定了解过这种设计模式,pipeline就像一个责任链,ChannelHandler就是其中处理逻辑的节点。

//创建一个逻辑处理器的抽象类
abstract class AbstractHandler {
//下一个逻辑处理器,如果你想双向传播,还可以定义一个前节点
AbstractHandler nextHandler;
//执行事件并往下传播
public void Execute(String message) {
write(message);
   //可以加上其他条件,终止传播
if (nextHandler != null)
nextHandler.Execute(message);
}
//设置下一个逻辑处理器
public void setNextHandler(AbstractHandler handler) {
this.nextHandler = handler;
}
//实际的逻辑方法,需要具体的逻辑处理器去实现
abstract void write(String message);
} //逻辑处理器A
class HandlerA extends AbstractHandler {
//实际的逻辑代码
@Override
void write(String message) {
System.out.println("逻辑处理器A执行:" + message);
}
}
//逻辑处理器B
class HandlerB extends AbstractHandler {
@Override
void write(String message) {
System.out.println("逻辑处理器B执行:" + message);
}
}
//逻辑处理器C
class HandlerC extends AbstractHandler {
@Override
void write(String message) {
System.out.println("逻辑处理器C执行:" + message);
}
}
//测试使用
public class Chain_ResponsibilityTest {
public static void main(String[] args) {
//首先创建逻辑处理器对象
AbstractHandler a = new HandlerA();
AbstractHandler b = new HandlerB();
AbstractHandler c = new HandlerC(); //把多个对象连成一条链
a.setNextHandler(b);
b.setNextHandler(c); //从头节点开始执行
a.Execute("你好");
}
}

  最后ABC会按照链表顺序输出你好。

3.单例模式

  单例模式的特点是一个类全局只有一个变量,创建时是线程安全的。
  常见单例模式实现的代码:

public class Singleton {
private static Singleton singleton;
private Singleton(){}
public static Singleton getInstance(){
if(singleton==null){
synchronized (Singleton.class){
if(singleton==null)
singleton=new Singleton();
}
}
return singleton;
}
}

  重点在于私有化构造函数,然后定义一个私有的静态全局变量,用以存储当前类的实例。向外提供一个获取实例的方法,如果当前实例变量不为空,说明已经实例化过,就直接返回。否则就进行实例化,为了防止多个线程同时进入if里面重复实例化,所以得加上synchronized。
  另外,单例模式还有懒汉、饿汉之分。上面的代码就是一个懒汉单例模式,即获取实例时才去创建,这和Netty中的延迟加载是一个思想。而饿汉就是,定义实例变量时直接实例化了,同样要私有化构造函数,之后获取实例的方法直接返回这个变量就行。
  单例模式在Netty中的应用:ReadTimeoutException等。

4.策略模式

  简答地说,一个类的行为或算法可以在运行时更改,这就策略模式。当一个类需要根据运行时的数据,自动去选择执行什么逻辑,这时候我们就可以用上策略模式。下面来简单实现一下:

//定义一个行为接口
interface Calculate{
int operation(int num1,int num2);
} //继承行为接口,实现具体的行为或算法
class StrategyAdd implements Calculate{
@Override
public int operation(int num1,int num2) {
return num1+num2;
}
}
class StrategyMultiply implements Calculate{
@Override
public int operation(int num1, int num2) {
return num1*num2;
}
}
//封装一个供外部使用的类
class Use{
private Calculate calculate;
//接收的参数是那个父接口,这样实现了这个接口的类都可以传递进来
public Use(Calculate calculate){
this.calculate=calculate;
}
public int execute(int num1,int num2){
//执行实际传递进来的类的operation方法
return calculate.operation(num1,num2);
}
}
public class Strategy {
//测试使用
public static void main(String[] args) {
//假设这不是main方法,只是实际项目中的一个普通方法,args是用户或其他路径传入的一个参数
//根据自己的实际需求甄别参数,选择具体行为
if(args.length==0){
Use use=new Use(new StrategyAdd());
System.out.println(use.execute(5,5));//
}else {
Use use1=new Use(new StrategyMultiply());
System.out.println(use1.execute(5,5));//
}
}
}

  Netty中的应用:DefaultEventExecutorChooserFactor-newChooser

5.装饰者模式

  不需要修改原有类的代码,就可以对这个类的对象附加其他效果。当要拓展一个类的功能时就可以使用这种设计模式。但这种设计模式的缺点也非常明显,会有额外的代码,当继承的层级多了以后,逻辑也更复杂。

//定义一个基础接口,获取商品价格
interface Goods{
float getPrice();
} //实现一个汽车商品,获取价格(原型)
class Car implements Goods{
private float Price;
public Car(float price){
this.Price=price;
}
@Override
public float getPrice() {
return Price;
} } //装饰者的父类,集中它们的优惠效果。如何集中的,关键在于装饰类获取价格方法时调用了父类的get方法。
//可以调试捋一捋,最终的价格计算其实是在打折时才开始一层层往上计算的
class On_Sale implements Goods{
private Goods goods;
public On_Sale(Goods goods){
this.goods=goods;
}
@Override
public float getPrice() {
return this.goods.getPrice();
}
} //汽车立减优惠(装饰者类,原型附加功能)
class Car_Knock extends On_Sale{
//立减金额
private float amount;
public Car_Knock(float amount,Goods goods){
super(goods);
this.amount=amount;
}
@Override
public float getPrice() {
return super.getPrice()-amount;
}
} //汽车打折优惠
class Car_Discount extends On_Sale{
//打折多少
private int discount;
public Car_Discount(int discount,Goods goods){
super(goods);
this.discount=discount;
}
@Override
public float getPrice() {
return super.getPrice()*discount/10;
}
}
//测试使用
public class decorator {
public static void main(String[] args) {
//创建一个原型,并传入价格
Goods goods=new Car(120000);
//当立减1000后
goods=new Car_Knock(1000,goods);
//在立减基础上再打个8折
goods=new Car_Discount(8,goods);
System.out.println(goods.getPrice());
}
}

  Netty中的应用:WrappedByteBuf、UnreleasableByteBuf、SimpleLeakAwareByteBuf。第一个类就相当于装饰者父类,后两个就是装饰类,而ByteBuf就是原型。

常用设计模式的实现,以及Netty中的设计模式的更多相关文章

  1. Java 设计模式六原则及23中常用设计模式

    一.设计模式的分类 总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接 ...

  2. netty系列之:netty中常用的字符串编码解码器

    目录 简介 netty中的字符串编码解码器 不同平台的换行符 字符串编码的实现 总结 简介 字符串是我们程序中最常用到的消息格式,也是最简单的消息格式,但是正因为字符串string太过简单,不能附加更 ...

  3. netty系列之:netty中常用的对象编码解码器

    目录 简介 什么是序列化 重构序列化对象 序列化不是加密 使用真正的加密 使用代理 Serializable和Externalizable的区别 netty中对象的传输 ObjectEncoder O ...

  4. netty中的发动机--EventLoop及其实现类NioEventLoop的源码分析

    EventLoop 在之前介绍Bootstrap的初始化以及启动过程时,我们多次接触了NioEventLoopGroup这个类,关于这个类的理解,还需要了解netty的线程模型.NioEventLoo ...

  5. 探究netty的观察者设计模式

    javadoc笔记点 观察者的核心思想就是,在适当的时机回调观察者的指定动作函数 我们知道,在使用netty创建channel时,一般都是把这个channel设置成非阻塞的模式,这意味着什么呢? 意味 ...

  6. Spring中的设计模式

    [Spring中的设计模式] http://www.uml.org.cn/j2ee/201301074.asp [详解设计模式在Spring中的应用]    [http://www.geek521.c ...

  7. 【转】Netty那点事(二)Netty中的buffer

    [原文]https://github.com/code4craft/netty-learning/blob/master/posts/ch2-buffer.md 上一篇文章我们概要介绍了Netty的原 ...

  8. Netty那点事: 概述, Netty中的buffer, Channel与Pipeline

    Netty那点事(一)概述 Netty和Mina是Java世界非常知名的通讯框架.它们都出自同一个作者,Mina诞生略早,属于Apache基金会,而Netty开始在Jboss名下,后来出来自立门户ne ...

  9. 访何红辉:谈谈Android源码中的设计模式

    最近Android 6.0版本的源代码开放下载,刚好分析Android源码的技术书籍<Android源码设计模式解析与实战>上市,我们邀请到它的作者何红辉,来谈谈Android源码中的设计 ...

随机推荐

  1. 【课程学习】课程2:十行代码高效完成深度学习POC

    本文用户记录黄埔学院学习的心得,并补充一些内容. 课程2:十行代码高效完成深度学习POC,主讲人为百度深度学习技术平台部:陈泽裕老师. 因为我是CV方向的,所以内容会往CV方向调整一下,有所筛检. 课 ...

  2. python填写问卷星,疫情上报

    #!!!注意:修改main里的url为真实的url,按需修改 50行 set_data中的submitdata # 61行 ip 修改为 真ip # submittype可能有错误,在151行 # 提 ...

  3. 玩转控件:Fucking ERP之流程图

    前言 首先,跟守护在作者公众号和私信作者催更的朋友们道个歉.疫情的原因,公司从年初到现在一直处于996+的高压模式,导致公众号更新频率较低.而且作者每更新一篇原创公众号,既要对自己沉淀知识负责,也要对 ...

  4. Mysql列属性

    列属性又称之为字段属性在mysql中一共有6个属性:null,默认值(default),列描述(comment),主键(primary key),唯一键(unique key)和自动增长 修改数据库字 ...

  5. CTO的窘境

    做CTO太难了,常年的coding思维让你早已与世隔绝,CTO有很好的技术方案,但CEO.CFO等O听不懂是很麻烦的事.总得来说,做CTO一定要技术背景出身,有很强的沟通能力和情商,敏锐的洞察力和决断 ...

  6. IDE使用GIT控制项目版本

    IDEA本身继承GIT开发插件.只需要安装windows git客户端即可使用. check in project 检入项目 将新创建的项目上传到服务器. 对于git来说,空的目录不会上传到远程仓库. ...

  7. python学习06循环

    '''while''''''while 布尔表达式:冒号不能省略''''''1+2+3+...+10'''i=1sum1=0while i<=10: sum1+=i i+=1print(sum1 ...

  8. Debugging Under Unix: gdb Tutorial (https://www.cs.cmu.edu/~gilpin/tutorial/)

    //注释掉 #include <iostream.h> //替换为 #include <iostream> using namespace std; Contents Intr ...

  9. Floyd-Warshall算法正确性证明

    以下所有讨论,都是基于有向无负权回路的图上的.因为这一性质,任何最短路径都不会含有环,所以也不讨论路径中包含环的情形!并且为避免混淆,将"最短路径"称为权值最小的路径,将路径经过的 ...

  10. Mozilla开始推送Firefox Preview 5.0版 支持画中画特性

    Mozilla 发布了 5.0 版本的 Firefox Preview 浏览器,根据 GitHub 上的发布说明,这次更新带来了一系列新的改进.其中包含对五个新的附加组件的支持,引入了对 Progre ...