没有找到合适的产品?
联系客服协助选型:023-68661681
提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
原创|其它|编辑:郝浩|2009-04-02 10:37:59.000|阅读 431 次
概述:如果你希望分离复杂类型构建规则和类型内部组成,或者希望把相同的构建过程用于构建不同类型的时候可以考虑使用建造者模式。如果你希望解耦产品的创建过程和产品的具体配件,或者你希望为所有产品的创建复用一套稳定并且复杂的逻辑的时候可以考虑使用建造者模式。
# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>
意图
把一个类的接口变换成客户端所期待的另一种接口,从而使原本接口不匹配而无法在一起工作的两个类能够在一起工作。
场景
假设网络游戏的客户端程序分两部分。一部分是和服务端通讯的大厅部分,大厅部分提供的功能有道具购买、读取房间列表、创建房间以及启动游戏程 序。另一部分就是游戏程序了,游戏程序和大厅程序虽然属于一个客户端,但是由不同的公司在进行开发。游戏大厅通过实现约定的接口和游戏程序进行通讯。
一开始的设计就是,大厅程序是基于接口方式调用游戏程序启动游戏场景方法的。在大厅程序开发接近完成的时候,公司决定和另外一家游戏公司合作, 因此希望把大厅程序能适用另一个游戏。而这个新游戏的遵循的是另一套接口。是不是可以避免修改原先调用方法来启动场景呢?或许你会说,既然只有一个方法修 改,那么修改一下也无妨,我们假设大厅程序和游戏程序之间有100个接口,其中的大部分都有修改呢?因为游戏程序接口的修改,大厅程序可能要修改不止 100个地方。这样接口的意义何在呢?
此时可以考虑使用Adapter模式来适配这种接口的不匹配情况。
示例代码
using System;
using System.Collections.Generic;
using System.Text;
namespace AdapterExample
{
class Program
{
static void Main(string[] args)
{
Lobby lobby = new Lobby();
lobby.CreateRoom("HalfPaper");
lobby.StartGame();
}
}
interface IGame
{
void StartScene(string sceneName);
void EnterPlayer(string playerName);
}
class Lobby
{
private string sceneName;
public void CreateRoom(string sceneName)
{
this.sceneName = sceneName;
}
public void StartGame()
{
IGame game = new GameAdapter();
game.StartScene(sceneName);
game.EnterPlayer("yzhu");
}
}
class Game
{
public void LoadScene(string sceneName, string token)
{
if (token == "Abcd1234")
Console.WriteLine("Loading " + sceneName + "...");
else
Console.WriteLine("Invalid token!");
}
public void EnterPlayer(int playerID)
{
Console.WriteLine("player:" + playerID + " entered");
}
}
class GameAdapter : IGame
{
private Game game = new Game();
public void StartScene(string sceneName)
{
game.LoadScene(sceneName, "Abcd1234");
}
public void EnterPlayer(string playerName)
{
game.EnterPlayer(GetPlayerIDByPlayerName(playerName));
}
private int GetPlayerIDByPlayerName(string playerName)
{
return 12345;
}
}
}
代码说明
可以看到,原先的接口中,启动游戏场景只需要一个参数,就是游戏场景名,而进入新的玩家需要提供玩家ID(新游戏都使用玩家ID而不使用玩家账户名)。
IGame接口就是适配器模式中的目标角色,这是客户所期待的接口。也是针对老的游戏程序所遵循的接口。
Lobby类相当于调用方或者客户,它原先的代码可能是如下的:
Game game = new Game();
但是由于接口的改变,现在不能直接实例化游戏类,只能实例化适配器类型。虽然还是需要改动,但是这个改动是很小的,而且完全可以通过用动态加载程序集来消除这种改动。
GameAdapter类是适配器角色,它是适配器模式的核心,用于把源接口转变为目标接口。在这里,我们看到,它实现目标接口。
Game类型是源角色,或者说是需要适配的对象。或许它也遵循了另外一套接口,不过我们不是很关心这个,因此代码中也没有体现。
使用了适配器模式后,客户端代码没有做什么修改。客户端代码老老实实的依赖接口,它并没有错,如果因此依赖对象的修改而需要大幅度修改就很无辜 了,我们在适配器中把本来没有关联的两个接口适配在了一起。我们可以看到,适配器做的不仅仅是换一换方法名,如果源角色和目标角色的差异非常大,那么适配 器需要做很多工作。
何时采用
从代码角度来说, 如果你希望分离复杂类型构建规则和类型内部组成,或者希望把相同的构建过程用于构建不同类型的时候可以考虑使用建造者模式。
从应用角度来说, 如果你希望解耦产品的创建过程和产品的具体配件,或者你希望为所有产品的创建复用一套稳定并且复杂的逻辑的时候可以考虑使用建造者模式。
实现要点
适配器模式是否能成功运用的关键在于代码本身是否是基于接口编程的,如果不是的话,那么适配器无能为力。
适配器模式的实现很简单,基本的思想就是适配器一定是遵循目标接口的。
适配器模式的变化比较多,可以通过继承和组合方式进行适配,适配器可以是一组适配器产品,适配器也可以是抽象类型。
适配器模式和Facade的区别是,前者是遵循接口的,后者可以是不遵循接口的,比较灵活。
适配器模式和Proxy的区别是,前者是为对象提供不同的接口,或者为对象提供相同接口,并且前者有一点后补的味道,后者是在设计时就会运用的。
注意事项
在对两个无关类进行适配的时候考虑一下适配的代价,一个非常庞大的适配器可能会对系统性能有影响。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com
文章转载自:自互联网面对“数字中国”建设和中国制造2025战略实施的机遇期,中车信息公司紧跟时代的步伐,以“集约化、专业化、标准化、精益化、一体化、平台化”为工作目标,大力推进信息服务、工业软件等核心产品及业务的发展。在慧都3D解决方案的实施下,清软英泰建成了多模型来源的综合轻量化显示平台、实现文件不失真的百倍压缩比、针对模型中的大模型文件,在展示平台上进行流畅展示,提升工作效率,优化了使用体验。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@evget.com
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢
慧都科技 版权所有 Copyright 2003-
2025 渝ICP备12000582号-13 渝公网安备
50010702500608号