当前位置: 首页 > news >正文

山西建站推广企业网站推广公司

山西建站推广,企业网站推广公司,数据管理系统网站模板,php网站下载文件怎么做学习设计模式不光要学习设计模式的思想,还要去深入理解,为什么要用这个设计模式。 如何深入理解?读优秀的框架代码,看别人代码,了解它们的使用场景。 - - - 博主老师(感谢他) 本文先介绍了适配器…

学习设计模式不光要学习设计模式的思想,还要去深入理解,为什么要用这个设计模式。
如何深入理解?读优秀的框架代码,看别人代码,了解它们的使用场景。 - - - 博主老师(感谢他)

本文先介绍了适配器模式的概念及简单实现。介绍了适配器模式在netty中的使用,最后总结了一点点思考。

适配器

  • 1、概念
  • 2、实现
    • 2.1 类适配器模式
    • 2.2 对象适配器模式
    • 2.3 接口适配器模式
  • 3、netty中的适配器模式
  • 4、思考

1、概念

定义:适配器模式把一个类的接口变换成客户端所期待的另一个接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。

假设我们公司有一个商城,商城里的商品都是我们预先定义好的一个类(classA)。现在突然和某公司谈了合作,要把他们的商品也放到我们商城卖,而他们的商品肯定和我们的商品不是一个类,他们的可能是classB。

我们现在要适配classB, 让它伪装成classA,提供和classA一样的功能

适配器做的主要工作就是为了让目标角色的API可以调用到源角色的API,适配器在中间做的是一个类似的中转作用,并且不影响源角色和目标角色原有的功能和逻辑。

2、实现

实现上面的例子:

首先定义我们的产品

public interface IProduct {void getName();void getPrice();
}
public class Product implements IProduct {@Overridepublic void getName() {System.out.println("产品名称");}@Overridepublic void getPrice() {System.out.println("产品价格");}
}

合作公司的产品

public interface IOther {// 友方公司代码写得比较烂... 他们的产品信息都放在了map里面Map<String, Object> getMsg();
}
public class Other implements IOther {@Overridepublic Map<String, Object> getMsg() {Map<String, Object> map = new HashMap<>();map.put("name", "其它公司产品名称");map.put("price", "其它公司产品价格");return map;}
}

2.1 类适配器模式

类适配器通过继承实现,由于Java不支持多继承,所以我们实现一个,继承一个。

public class ProductAdapter extends Other implements IProduct {@Overridepublic void getName() {Map<String, Object> map = getMsg();System.out.println(map.get("name"));}@Overridepublic void getPrice() {Map<String, Object> map = getMsg();System.out.println(map.get("price"));}
}

测试:

public static void main(String[] args) {IProduct product = new ProductAdapter();product.getName();product.getPrice();
}

2.2 对象适配器模式

对象适配器模式通过聚合的方式实现

public class ProductAdapter2 implements IProduct {private IOther iOther;public ProductAdapter2(IOther iOther) {this.iOther = iOther;}@Overridepublic void getName() {System.out.println(iOther.getMsg().get("name"));}@Overridepublic void getPrice() {System.out.println(iOther.getMsg().get("price"));}
}
IProduct product2 = new ProductAdapter2(new Other());
product2.getName();
product2.getPrice();
其它公司产品名称
其它公司产品价格

2.3 接口适配器模式

在学习适配器模式的过程中,网上有些文章还写到了接口适配器模式(缺省适配模式)。博主它并不属于23种设计模式中适配器模式的范畴。(个人观点,仅供参考。如果有误,敬请指正!)

虽然博主认为不是,但不妨碍我们介绍它:

接口适配器模式的思想是为一个接口提供缺省实现,这样子类可以从这个缺省实现进行扩展,而不必从原有接口进行扩展。
在jdk源码中有个典型的例子

package java.awt.event;import java.util.EventListener;public interface KeyListener extends EventListener {public void keyTyped(KeyEvent e);public void keyPressed(KeyEvent e);public void keyReleased(KeyEvent e);
}
package java.awt.event;public abstract class KeyAdapter implements KeyListener {/*** Invoked when a key has been typed.* This event occurs when a key press is followed by a key release.*/public void keyTyped(KeyEvent e) {}/*** Invoked when a key has been pressed.*/public void keyPressed(KeyEvent e) {}/*** Invoked when a key has been released.*/public void keyReleased(KeyEvent e) {}
}

KeyAdapter空实现了KeyListener接口。为了子类实现接口的时候,只需要重写自己想要的方法,而不需要把接口的所有方法都写一遍。例如,我们只想实现keyPressed方法:

frame.addKeyListener(new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {System.out.println("fxcku!");}
});

在Java8之后,其实并不需要这么麻烦。我们可以用default关键字为接口写默认的实现,可以改造成:

package java.awt.event;import java.util.EventListener;public interface KeyListener extends EventListener {public default void keyTyped(KeyEvent e) {};public default void keyPressed(KeyEvent e) {};public default void keyReleased(KeyEvent e) {};
}

使用

frame.addKeyListener(new KeyListener() {@Overridepublic void keyPressed(KeyEvent e) {System.out.println("fxcku!");}
});

3、netty中的适配器模式

ScheduledFutureTask是Netty当中的异步定时任务。任务可以是Runnale, 也可以是带返回结果的Callable
而netty最终去执行任务的时候,其实调用的是Callable的call方法。如果用户传的是Runnale,netty使用了适配器模式让两个任务接口无缝衔接。

ScheduledFutureTask的两个构造方法,如果是Runnable,调用了父类的toCallable()

package io.netty.util.concurrent;final class ScheduledFutureTask<V> extends PromiseTask<V> implements ScheduledFuture<V>, PriorityQueueNode {ScheduledFutureTask(AbstractScheduledEventExecutor executor,Runnable runnable, V result, long nanoTime) {this(executor, toCallable(runnable, result), nanoTime);}ScheduledFutureTask(AbstractScheduledEventExecutor executor,Callable<V> callable, long nanoTime, long period) {super(executor, callable);if (period == 0) {throw new IllegalArgumentException("period: 0 (expected: != 0)");}deadlineNanos = nanoTime;periodNanos = period;}
}

父类的toCallable方法,返回了一个适配器,我们可以看到,它是一个对象适配器。
最终,在run方法里面,调用的是task.call()方法。

class PromiseTask<V> extends DefaultPromise<V> implements RunnableFuture<V> {static <T> Callable<T> toCallable(Runnable runnable, T result) {return new RunnableAdapter<T>(runnable, result);}private static final class RunnableAdapter<T> implements Callable<T> {final Runnable task;final T result;RunnableAdapter(Runnable task, T result) {this.task = task;this.result = result;}@Overridepublic T call() {task.run();return result;}@Overridepublic String toString() {return "Callable(task: " + task + ", result: " + result + ')';}}protected final Callable<V> task;@Overridepublic void run() {try {if (setUncancellableInternal()) {V result = task.call();setSuccessInternal(result);}} catch (Throwable e) {setFailureInternal(e);}}
}

4、思考

个人认为适配器模式把握住一个核心:兼容两个不同的api
适配器模式在为不方便重构旧类(旧的类可能在jar包里)又需要做到兼容的情况提供了良好的解决方案。

但是正如很多书本、文章所说:过多的适配器会让系统造成凌乱(明明调用的是接口A, 被适配成了接口B)。还是灵活使用吧,一般是在稳定的系统基础上,去加的,而不是一开始这么设计。

http://www.lbrq.cn/news/2804779.html

相关文章:

  • 网站建设ppt介绍关键词优化网站排名
  • 做app好还是响应式网站广告推广渠道有哪些
  • 门户网站建设工作室百度竞价推广联系方式
  • 做网站用哪个编程语言河南网站推广多少钱
  • 武汉做网站 九州科技bt兔子磁力搜索
  • 网站界面尺寸大小门户网站怎么做
  • 如何加强省市网站建设100个经典创意营销方案
  • 网站制作公司交接网站服务器信息查询
  • 城市分站cms怎么做网络推广
  • 网站建设 百度推广网站优化公司哪家效果好
  • 制作网站服务公司app开发需要哪些技术
  • ppt做长图网站网络营销推广公司简介
  • 做网站图片素材在线编辑网店推广网站
  • 怎么让百度收录我的网站优化关键词软件
  • ecshop外贸网站黄页网络的推广网站有哪些
  • 门户网站建设内在百度上打广告找谁推广产品
  • 温州市网站制作哪家便宜nba西部最新排名
  • 网站运维工作内容cctv 13新闻频道
  • 网站推广途径和要点有哪些沈阳关键词自然排名
  • bootstrap 新闻网站模板网店推广实训报告
  • 多用户网站建设查网站排名
  • 5星做号宿水软件的网站广丰网站seo
  • 阳泉做网站多少钱百度天眼查
  • 网站报错500竞价什么意思
  • 巩义云启网站建设深圳网站制作公司
  • 服装租赁 网站 php杭州旺道企业服务有限公司
  • 西安个人建网站百度站长平台链接提交
  • 自己做网站的好处河池网站seo
  • 做网站建设优化的公司百度有钱花人工客服
  • 江西省赣州市崇义县搜狗整站优化
  • Unity--判断一个点是否在扇形区域里面(点乘和叉乘的应用)
  • 力扣(在排序数组中查找元素的第一个和最后一个位置)
  • Python 中 SQLAlchemy 和 MySQLdb 的关系
  • hadoop-3.3.6和hbase-2.4.13
  • 2025-08-21 Python进阶1——控制流语句
  • 从vue2到vue3