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

如何选择建设网站类型做园区门户网站的需求分析

如何选择建设网站类型,做园区门户网站的需求分析,wordpress批量导入用户,廊坊做网站公司哪家好在这篇文章中#xff0c;我将探讨依赖注入#xff08;DI#xff09;和控制反转#xff08;IoC#xff09;是什么#xff0c;以及它们的重要性。作为示例#xff0c;我将使用Monibot的REST API客户端。让我们开始吧#xff1a; 一个简单的客户端实现 我们从一个简单的…在这篇文章中我将探讨依赖注入DI和控制反转IoC是什么以及它们的重要性。作为示例我将使用Monibot的REST API客户端。让我们开始吧 一个简单的客户端实现 我们从一个简单的客户端实现开始允许调用者访问Monibot的REST API具体来说是为了发送指标值。客户端的实现可能如下所示 package monibottype Client struct { }func NewClient() *Client {return Client{} }func (c *Client) PostMetricValue(value int) {body : fmt.Sprintf(value%d, value)http.Post(https://monibot.io/api/metric, []byte(body)) } 这里有一个客户端提供了PostMetricValue方法该方法用于将指标值上传到Monibot。我们的库的用户可能像这样使用它 import monibotfunc main() {// 初始化API客户端client : monibot.NewClient()// 发送指标值client.PostMetricValue(42) } 依赖注入 现在假设我们想对客户端进行单元测试。当所有HTTP发送代码都是硬编码的时候我们如何测试客户端呢对于每次测试运行我们都需要一个“真实”的HTTP服务器来回答我们发送给它的所有请求。不可取我们可以做得更好让我们将HTTP处理作为“依赖”让我们发明一个 Transport 接口 package monibot// Transport传输请求。 type Transport interface {Post(url string, body []byte) } 让我们再发明一个具体的使用HTTP作为通信协议的Transport package monibot// HTTPTransport是一个使用HTTP协议传输请求的Transport。 type HTTPTransport struct { }func (t HTTPTransport) Post(url string, data []byte) {http.Post(url, data) } 然后让我们重写客户端使其“依赖”于一个Transport 接口 package monibottype Client struct {transport Transport }func NewClient(transport Transport) *Client {return Client{transport} }func (c *Client) PostMetricValue(value int) {body : fmt.Sprintf(value%d, value)c.transport.Post(https://monibot.io/api/metric, []byte(body)) } 现在客户端将请求转发到它的Transport依赖。当创建客户端时transport客户端的依赖项被“注入”到客户端中。调用者可以这样初始化一个客户端 import monibotfunc main() {// 初始化API客户端var transport monibot.HTTPTransportclient : monibot.NewClient(transport)// 发送指标值client.PostMetricValue(42) } 单元测试 现在我们可以编写一个使用“伪造”Transport的单元测试 // TestPostMetricValue确保客户端向REST API发送正确的POST请求。 func TestPostMetricValue(t *testing.T) {transport : fakeTransport{}client : NewClient(transport)client.PostMetricValue(42)if len(transport.calls) ! 1 {t.Fatal(期望1次传输调用但是是%d次, len(transport.calls))}if transport.calls[0] ! POST https://monibot.io/api/metric, body\\value42\\ {t.Fatal(错误的传输调用 %q, transport.calls[0])} }// 伪造的Transport是单元测试中使用的Transport。 type fakeTransport struct {calls []string }func (f *fakeTransport) Post(url string, body []byte) {f.calls append(f.calls, fmt.Sprintf(POST %v, body%q, url, string(body))) } 添加更多的Transport函数 现在假设我们库的其他部分也使用了Transport功能需要比POST更多的HTTP方法。对于它们我们必须扩展我们的Transport接口 package monibot// Transport传输请求。 type Transport interface {Get(url string) []byte // 添加因为health-monitor需要Post(url string, body []byte)Delete(url string) // 添加因为resource-monitor需要 } 现在我们有一个问题。编译器抱怨我们的fakeTransport不再满足Transport接口。所以让我们通过添加缺失的函数来解决它 // 伪造的Transport是单元测试中使用的Transport。 type fakeTransport struct {calls []string }func (f *fakeTransport) Get(url string) []byte {panic(不使用) }func (f *fakeTransport) Post(url string, body []byte) {f.calls append(f.calls, fmt.Sprintf(POST %v, body%q, url, string(body))) }func (f *fakeTransport) Delete(url string) {panic(不使用) } 我们做了什么由于在单元测试中我们不需要新的Get()和Delete()函数如果它们被调用我们就抛出异常。这里有一个问题每次在Transport中添加新函数时我们都会破坏现有的fakeTransport实现。对于大型代码库来说这将导致维护噩梦。我们能做得更好吗 控制反转 问题在于我们的客户端和相应的单元测试依赖于一个它们不能控制的类型。在这种情况下它是Transport接口。为了解决这个问题让我们通过引入一个未导出的接口该接口仅声明了我们的客户端所需的内容来反转控制 package monibot// clientTransport传输Client的请求。 type clientTransport interface {Post(url string, body []byte) }type Client struct {transport clientTransport }func NewClient(transport clientTransport) *Client {return Client{transport} }func (c *Client) PostMetricValue(value int) {body : fmt.Sprintf(value%d, value)c.transport.Post(https://monibot.io/api/metric, []byte(body)) } 现在让我们将我们的单元测试更改为使用假的clientTransport // TestPostMetricValue确保客户端向REST API发送正确的POST请求。 func TestPostMetricValue(t *testing.T) {transport : fakeTransport{}client : NewClient(transport)client.PostMetricValue(42)if len(f.calls) ! 1 {t.Fatal(期望1次传输调用但是是%d次, len(f.calls))}if f.calls[0] ! POST https://monibot.io/api/metric, body\\value42\\ {t.Fatal(错误的传输调用 %q, f.calls[0])} }// 伪造的Transport是在单元测试中使用的clientTransport。 type fakeTransport struct {calls []string }func (f *fakeTransport) Post(url string, body []byte) {f.calls append(f.calls, fmt.Sprintf(POST %v, body%q, url, string(body))) } 由于Go的隐式接口实现如果愿意可以称之为’鸭子类型’我们库的用户什么也不需要改变 import monibotfunc main() {// 初始化API客户端var transport monibot.HTTPTransportclient : monibot.NewClient(transport)// 发送指标值client.PostMetricValue(42) } 重新审视Transport 如果我们使IoC成为规范正如我们应该做的那样就不再需要导出Transport接口了。为什么呢因为如果消费者需要一个接口让他们在自己的作用域中定义它就像我们对’clientTransport’做的那样。 不要导出接口。导出具体实现。如果消费者需要接口让他们在自己的作用域中定义。 总结 在这篇文章中我展示了如何以及为什么在Go中使用DI和IoC。正确使用DI/IoC可以导致更易于测试和维护的代码特别是在代码库不断增长时。虽然代码示例是用Go编写的但这里描述的原则同样适用于其他编程语言。
http://www.zqtcl.cn/news/565311/

相关文章:

  • vue做前台网站怎么做钓鱼网站吗
  • 个人建设网站如何定位烟台h5网站开发
  • 广州网站定制多少钱html5游戏开发
  • 使用angularjs的网站域名怎么解析到服务器
  • 地方门户网站盈利模式宝塔 wordpress
  • 西安网站备案软件开发基础教程
  • 有服务器做网站软件系统开发怎样容易
  • 网站建设的公司有发展吗织梦婚纱网站模板
  • 淘宝销售书网站建设方案wordpress调用评论数据
  • 搭建网站需要什么软件苏州吴中区建设局工程网站
  • 长沙市网站推广公司wordpress 弹窗登录插件
  • 网站策划怎么做内容朔州网站建设公司
  • 宁波拾谷网站建设蚌埠网站建设中心
  • 青岛专业设计网站公司加拿大广播公司
  • 盘锦市建设局网站地址八桂职教网技能大赛
  • 投资建设一个网站多少钱和淘宝同时做电商的网站
  • 做动物网站的素材icp备案 网站备案
  • 找人建网站唐山网络运营推广
  • 福建省住房建设厅网站6网站简历模板
  • 医疗网站模版杭州工商注册
  • 正保建设工程网站logo创意
  • 简洁个人博客网站模板下载用自己电脑做网站服务器-phpstudy+花生壳
  • 网页模板下载哪个网站好多个域名指定同一个网站好处
  • 北京网站建设有哪些公司微网站的案例
  • 常德经开区网站官网域名备案关闭网站吗
  • 做宠物网站的工作室做网站租服务器
  • 2017做那个网站致富网站换源码如何保留以前的文章
  • php网站开发实例教程书wordpress博客页面显示文章在哪
  • 地方o2o同城网站源码微信app开发价格表
  • 花木公司网站源码双语外贸网站源码