C# 将许多方法中使用的一个硬编码字符串重构为两个
我有一个类似于下面的情况。它是一个RESTAPI助手类,具有用于不同API端点的方法,并向其提供头。一个标题ChannelId已硬编码为“Channel 1” 从现在起,应该有可能改用“通道2”。什么是重构这个的好策略?我已经提出了我的建议,但不知何故,这似乎是一种廉价的方式。因为我需要改变很多方法中的签名C# 将许多方法中使用的一个硬编码字符串重构为两个,c#,refactoring,C#,Refactoring,我有一个类似于下面的情况。它是一个RESTAPI助手类,具有用于不同API端点的方法,并向其提供头。一个标题ChannelId已硬编码为“Channel 1” 从现在起,应该有可能改用“通道2”。什么是重构这个的好策略?我已经提出了我的建议,但不知何故,这似乎是一种廉价的方式。因为我需要改变很多方法中的签名 public class RestApiRequestHelper { public void MethodA() { var request = new R
public class RestApiRequestHelper
{
public void MethodA()
{
var request = new RestRequest(RestRequest.GET);
AddHeaders(request);
//...
}
//... more similar methods using AddHeaders(request)
public void MethodZ()
{
var request = new RestRequest(RestRequest.GET);
AddHeaders(request);
//...
}
private void AddHeaders(RestRequest request)
{
request.AddHeader("ChannelId", "Channel 1");
//...
}
}
我的建议是:
public class RestApiRequestHelper
{
public void MethodA(string channelId)
{
var request = new RestRequest(RestRequest.GET);
AddHeaders(request, channelId);
//...
}
//... more similar methods using AddHeaders(request)
public void MethodZ(string channelId)
{
var request = new RestRequest(RestRequest.GET);
AddHeaders(request, channelId);
//...
}
private void AddHeaders(RestRequest request, string channelId)
{
request.AddHeader("ChannelId", channelId);
//...
}
}
从API消费者的角度来看,新版本是一个突破性的变化,而且很容易出错
- 突破性变化:消费者必须适应新的API,因为它不向后兼容
- 容易出错:消费者现在几乎可以用任何东西调用此API,例如:
,null
,“ThisIsNotExistingChannelId”
,“ThisisMisspelledChannelId”
,等等等待长时间运行操作ToobtainChannelId()
公共无效方法A(字符串channelId=“通道1”)
{
var请求=新的RestRequest(RestRequest.GET);
addHeader(请求,channelId);
//...
}
具有回退值的参数
public void MethodA(字符串channelId=default)
{
var请求=新的RestRequest(RestRequest.GET);
AddHeader(请求,通道ID??“通道1”);
//...
}
参数限制
如果您不想允许任何类型的通道标识符,那么您也可以限制它
运行时检查
私有静态只读不可变数组
ValidChannelIds=ImmutableArray.Create(“通道1”、“通道2”);
public void MethodA(字符串channelId=default)
{
如果(!ValidChannelIds.Contains(channelId))
抛出新ArgumentOutOfRangeException(nameof(channelId)),
$“提供的通道无效。有效ID为:{string.Join(',',ValidChannelIds)}'”;
...
}
编译时和运行时检查
公共枚举通道
{
[说明(“频道1”)]
Ch1=0,
[说明(“频道2”)]
Ch2=2,
}
公共无效方法A(通道channelId=Channels.Ch1)
{
如果(!Enum.IsDefined(typeof(Channels),channelId))
抛出新ArgumentOutOfRangeException(nameof(channelId)),
$“提供的通道无效。有效ID:“{string.Join(',',Enum.GetNames(typeof(通道)))}”;
var fieldInfo=typeof(Channels.GetField(channelId.ToString(“G”));
var chId=fieldInfo.GetCustomAttribute().Description;
...
}
需要
Enum.IsDefined
,因为您也可以这样调用方法:MethodA((Channels)3)代码>和3没有说明
为什么没有?这是正常的,您也可以将其提取到扩展方法AddChannelIdHeader(此重新请求请求,字符串channelId){request.AddHeader(“channelId”,channelId);}
。如果您的“channel2”方法与channel1不相关,您可以添加另一个方法,将头添加到请求中。在您回答之前,我选择了“带默认值的参数”选项,但非常感谢您的回答。