当前位置:网站首页>Declare war on uncivilized code I
Declare war on uncivilized code I
2022-06-21 13:42:00 【Guo Mahua】
A lot of people talk about technology architecture , But I can't bear to look straight at the code .
June to present , I took over and maintained several projects . I am mainly responsible for some projects , I will optimize and refactor little by little . Some items are hand - made changes . but , Just a little bit of code change ,VS The author will become himself .
I'm afraid of , I'm afraid the people behind me will point at my name and scold ,“ What is it all about !”
I am responsible for the docking of major real estate platforms in the market , The code in this article is developed according to the open document of the platform , It does not involve the company's data business .

I sent a code specification earlier , Some people spit on me , I quietly deleted it , Today I released it again .“ my “ C# Code specification
Among them, the one who has been roast most is :“ A function should preferably not exceed ten lines .”
Some people say : impossible , Few businesses can be written in ten lines !
Let me give some examples of code transformation , To explain why the shorter the function, the better .
You don't need to know anything about it in advance , The code can be clearer than the documentation :
Case a 123 House watching VR Push to real estate platforms such as anjuke 123 Look at the official documents
Code logic before transformation :
1. receive Rabbitmq Message concurrent processing , Get into TryPublishAsync Method

2. High energy warning Horrible TryPublishAsync Method
public async ValueTask TryPublishAsync(Guid houseId, string houseTypeValue, string houseTypeName, string matchKey, List<string> targetProviderNames,
IDictionary<string, string> payload = null,
CancellationToken cancellationToken = default)
{
targetProviderNames ??= new();
var houseTask = await _taskRepository.GetAll()
.Where(x => x.HouseId == houseId && x.StatusValue == 3)
.OrderByDescending(x => x.FinishTime)
.FirstOrDefaultAsync(cancellationToken);
if (houseTask is null)
{
return;
}
foreach (var targetProviderName in targetProviderNames)
{
if (string.IsNullOrWhiteSpace(targetProviderName))
{
continue;
}
var publishLog = new HousePublishLog()
{
HouseId = houseTask.HouseId,
CaptureHouseTaskId = houseTask.Id,
HouseTypeValue = houseTypeValue,
HouseTypeName = houseTypeName,
SourceProviderName = houseTask.Provider,
CompanyId = houseTask.CompanyId,
CityId = houseTask.CityId,
TargetProviderName = targetProviderName
};
if (targetProviderName == "fangtianxia")
{
try
{
var captureHouseTaskService = _captureHouseTaskServiceFactory.Create(publishLog.SourceProviderName);
var rootToken = await _tokenManager.GetAsync(publishLog.SourceProviderName, null, null, cancellationToken);
if (payload is not null && payload.Count is not 0)
{
string fangTianXiaCommunityName = null, fangTianXiaHouseId = null, fangTianXiaPurposeType = null;
payload?.TryGetValue("communityName", out fangTianXiaCommunityName);
payload?.TryGetValue("houseId", out fangTianXiaHouseId);
payload?.TryGetValue("purposeType", out fangTianXiaPurposeType);
if (string.IsNullOrWhiteSpace(fangTianXiaCommunityName))
{
fangTianXiaCommunityName = houseTask.CommunityName;
}
if (string.IsNullOrWhiteSpace(fangTianXiaHouseId))
{
fangTianXiaHouseId = null;
}
if (string.IsNullOrWhiteSpace(fangTianXiaPurposeType))
{
fangTianXiaPurposeType = null;
}
await captureHouseTaskService.PutFangtianxiaInfoAsync(rootToken, new(houseTask.ProviderPackageId, fangTianXiaCommunityName, fangTianXiaPurposeType, fangTianXiaHouseId), cancellationToken);
}
var notifyResult = await captureHouseTaskService.NotifyAsync(rootToken, new(houseTask.ProviderPackageId, houseTask.CompanyId.ToString(), targetProviderName), cancellationToken);
switch (notifyResult.notifyResult)
{
case 0:
publishLog.ErrorMessage = " Not notified ";
break;
case 1:
publishLog.Success = true;
publishLog.ErrorMessage = " Successful notification ";
break;
case 2:
publishLog.ErrorMessage = " The customer interface refused ";
break;
case 3:
publishLog.ErrorMessage = " Error in push ";
break;
default:
publishLog.ErrorMessage = $" Unknown notifyResult: {notifyResult}";
break;
}
}
catch (OneTwoThreeKanFangApiException e)
{
houseTask.ProviderTaskCancellationRequestContent = e.RequestContent;
houseTask.ProviderTaskCancellationResponseContent = e.ResponseContent;
publishLog.ErrorMessage = $" Attempt to publish Internet failed : state: {e.Response?.state}, message: {e.Message}";
throw;
}
finally
{
await _housePublishLogRepository.InsertAsync(publishLog);
await _messageBus.PublishAsync(new TryNotifyResponseMessage
{
Success = publishLog.Success,
ErrorMessage = publishLog.ErrorMessage,
HouseId = houseId.ToString()
}, cancellationToken: cancellationToken);
}
}
else if (targetProviderName == "58")
{
try
{
var captureHouseTaskService = _captureHouseTaskServiceFactory.Create(publishLog.SourceProviderName);
var rootToken = await _tokenManager.GetAsync(publishLog.SourceProviderName, null, null, cancellationToken);
if ((!string.IsNullOrWhiteSpace(matchKey)) && (matchKey != houseId.ToString()))
{
await captureHouseTaskService.ChangeAnjukeBianHaoAsync(rootToken, new(houseTask.ProviderPackageId, matchKey), cancellationToken);
}
var notifyResult = await captureHouseTaskService.NotifyAsync(rootToken, new(houseTask.ProviderPackageId, houseTask.CompanyId.ToString(), targetProviderName), cancellationToken);
switch (notifyResult.notifyResult)
{
case 0:
publishLog.ErrorMessage = " Not notified ";
break;
case 1:
publishLog.Success = true;
publishLog.ErrorMessage = " Successful notification ";
break;
case 2:
publishLog.ErrorMessage = " The customer interface refused ";
break;
case 3:
publishLog.ErrorMessage = " Error in push ";
break;
default:
publishLog.ErrorMessage = $" Unknown notifyResult: {notifyResult}";
break;
}
}
catch (OneTwoThreeKanFangApiException e)
{
houseTask.ProviderTaskCancellationRequestContent = e.RequestContent;
houseTask.ProviderTaskCancellationResponseContent = e.ResponseContent;
publishLog.ErrorMessage = $" Attempt to publish Internet failed : state: {e.Response?.state}, message: {e.Message}";
throw;
}
finally
{
await _housePublishLogRepository.InsertAsync(publishLog);
await _messageBus.PublishAsync(new TryNotifyResponseMessage
{
Success = publishLog.Success,
ErrorMessage = publishLog.ErrorMessage,
HouseId = houseId.ToString()
}, cancellationToken: cancellationToken);
}
}
}
}3. It's not over yet. , The above is just the business process code , The specific docking code is the following paragraph :
public async ValueTask<NotifyHouseTaskResponseDto> NotifyAsync(TokenDto rootToken, NotifyHouseTaskRequestDto request, CancellationToken cancellationToken = default)
{
var options = _oneTwoThreeKanFangProviderOptionsAccessor.Value;
var notifyConfigId = request.channel switch
{
"58" => options.AnJuKe?.NotifyConfigId,
"fangtianxia" => options.FangTianXia?.NotifyConfigId,
_ => default(string),
};
if (string.IsNullOrWhiteSpace(notifyConfigId))
{
throw new AppException(" Not configured notifyConfigId");
}
string payload = "{}";
if (string.IsNullOrWhiteSpace(request.payloadType))
{
payload = [email protected]"{
{""type"":""{request.payloadType}""}}";
}
using var http = _httpClientFactory.CreateClient(nameof(OneTwoThreeKanFangCaptureHouseTaskService));
var response = await http.V2_houseTask_AddNewNotifyTaskByPackageID(
options.ApiEndpoint,
rootToken.token,
notifyConfigId,
request.packageId,
logger: _logger,
cancellationToken: cancellationToken
);
if (response is null)
{
throw new AppException(" Failed to request house source data package push ");
}
return new(response.id, response.notifyResult ?? -1, response.notifyConfigId, response.houseTaskId);
}
public async ValueTask<PutFangtianxiaInfoResponseDto> PutFangtianxiaInfoAsync(TokenDto rootToken, PutFangtianxiaInfoRequestDto request, CancellationToken cancellationToken = default)
{
var options = _oneTwoThreeKanFangProviderOptionsAccessor.Value;
var notifyConfigId = options.FangTianXia?.NotifyConfigId;
if (string.IsNullOrWhiteSpace(notifyConfigId))
{
throw new AppException(" Not configured notifyConfigId");
}
using var http = _httpClientFactory.CreateClient(nameof(OneTwoThreeKanFangCaptureHouseTaskService));
var response = await http.V2_houseTask_PutFangtianxiaInfo(
options.ApiEndpoint,
rootToken.token,
request.packageId,
request.communityName,
request.houseId,
request.purposeType,
logger: _logger,
cancellationToken: cancellationToken
);
if (response is null)
{
throw new AppException(" Failed to modify anjuke number ");
}
return new(response?.AdditionalData);
}I believe that no one knows what they are writing at a glance , I am also , Like a child who can't describe clearly .
So I clenched my teeth and reread 123 House viewing document , Rewrote VR Push content .
Code logic after transformation :
1. receive MQ Message concurrent processing
Here to MQ The message body is greatly simplified , A large number of useless fields have been deleted , And the field name is modified , More in line with The overall logic of the project .

2. Will be huge and bloated TryPublishAsync Method is split into vrPushService, And provide release VR To the function of anjuke and SouFun , See above .
The original TryPublishAsync Functions are extremely bloated , Here we will disassemble them one by one :
- VR package Id Query for : Put it in MQ Query in the message receiving method , And call... As a parameter VRPushService Related methods .
- logging : 123 The backstage provides log query function , Delete directly .
- Token obtain : There is no need to act public Methods provided externally , Hidden as a private method in VRPushService among .
- establish VR Push some related predecessor tasks : There is no need to act public Methods provided externally , Hidden as a private method in VRPushService among .
- establish VR Push task
Above contents , The original code relied on at least three services to provide , And actually use factory methods to get related business processing classes , This over encapsulates , What is the point of using dependency injection ?
There's no show here Token The code of the acquisition and the predecessor task implements , Can't bear to look straight ahead. .
Transformed VRPushService.cs No more than ten lines per function , Logic is clearly visible
public class VRPushService : IVRPushService
{
private readonly IOptions<OneTwoThreeKanFangProviderOptions> _option;
public VRPushService(IOptions<OneTwoThreeKanFangProviderOptions> option)
{
_option = option;
}
/// <summary>
/// VR Push fangtianxia
/// </summary>
/// <param name="packageId"></param>
/// <param name="listingId"></param>
/// <param name="communityName"></param>
/// <param name="purposeType"></param>
/// <returns></returns>
public async Task<ResultDto> PushFTXAsync(string packageId, string listingId, string communityName, string purposeType)
{
var token = await GetTokenAsync();
var preResult = await FTXPreTask(token, packageId, listingId, communityName, purposeType);
if (preResult.State != 200)
throw new Exception($"{preResult.Msg}-{preResult.Payload}");
return await CreateTask(token, packageId, _option.Value.FangTianXia.NotifyConfigId);
}
/// <summary>
/// VR push 58 Anju
/// </summary>
/// <param name="packageId"></param>
/// <param name="listingCode"></param>
/// <returns></returns>
public async Task<ResultDto> Push58Async(string packageId, string listingCode)
{
var token = await GetTokenAsync();
var preResult = await _58PreTask(token, packageId, listingCode);
if (preResult.State != 200)
throw new Exception($"{preResult.Msg}-{preResult.Payload}");
return await CreateTask(token, packageId, _option.Value.AnJuKe.NotifyConfigId);
}
/// <summary>
/// VR Internet push
/// </summary>
/// <param name="token"></param>
/// <param name="content"></param>
/// <returns></returns>
public async Task<ResultDto> CreateTask(string token, string packageId, string notifyconfigId)
{
var content = new Dictionary<string, string>
{
{ "packageId",packageId},
{ "notifyconfigId",notifyconfigId},
{ "forcePush", "true"}
};
return await PostAsync(token, $"{_option.Value.ApiEndpoint}/v2/houseTask/AddNewNotifyTaskByPackageID", content);
}
/// <summary>
/// 58VR Push predecessors
/// </summary>
/// <param name="token"></param>
/// <param name="packageId"></param>
/// <param name="listingCode"></param>
/// <returns></returns>
private async Task<ResultDto> _58PreTask(string token, string packageId, string listingCode)
{
var content = new Dictionary<string, string>
{
{ "packageId", packageId},
{ "anjukeBianHao", listingCode},
};
return await PostAsync(token, $"{_option.Value.ApiEndpoint}/v2/houseTask/putAnjukeBianHao", content);
}
/// <summary>
/// Fangtianxia VR Push predecessors
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
private async Task<ResultDto> FTXPreTask(string token, string packageId, string listingId, string communityName, string purposeType)
{
var content = new Dictionary<string, string>
{
{ "packageId", packageId},
{ "communityName", communityName},
{ "purposeType", purposeType},
{ "houseId", listingId}
};
return await PostAsync(token, $"{_option.Value.ApiEndpoint}/v2/houseTask/PutFangtianxiaInfo", content);
}
private async Task<ResultDto> PostAsync(string token, string url, Dictionary<string, string> content)
{
using var httpClient = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = new FormUrlEncodedContent(content)
};
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", token);
var response = await httpClient.SendAsync(request);
return await response.Content.ReadFromJsonAsync<ResultDto>();
}
private async Task<string> GetTokenAsync()
{
using var httpClient = new HttpClient();
var result = await httpClient.GetFromJsonAsync<ResultDto>($"{_option.Value.ApiEndpoint}/v2/Authorization/GetAccessToken?" +
$"AuthKey={_option.Value.Account}&AuthValue={_option.Value.Password}&ClientEdtion=ps_1.0.0");
return result.Entity<TokenDto>().Token;
}
}Transformation completed , And online . alas , Heart tired !
边栏推荐
- [deeply understand tcapulusdb technology] tcapulusdb import data
- Two common schemes for handling interface idempotence
- Is the micro securities account opening regular and safe? How to open an account?
- Automation operation and maintenance 1 - installation and deployment of ansible
- Lamp architecture 4 -- MySQL source code compilation and use
- Implementation of queue
- MySQL - table constraints
- Implementation principle and application practice of Flink CDC mongodb connector
- How to use search engine?
- Navigation bar switching, message board, text box losing focus
猜你喜欢

【课程作业】浮点运算分析及精度改进

Is the live interactive function of the applet running in the app?

Heat mapping using Seaborn
![[deeply understand tcapulusdb technology] tmonitor background one click installation](/img/0a/742503e96a9b51735f5fd3f598b9af.png)
[deeply understand tcapulusdb technology] tmonitor background one click installation

如何阅读AI顶会论文?
MySQL约束(创建表时的各种条件说明)

MySQL - table operation

MySQL - transaction management

Automatic operation and maintenance 2 - common modules in ansible

SCCM基于已安装的 APP创建客户端集合并定期推送应用更新
随机推荐
Highly available configuration of database (MySQL)
Kube Prometheus grafana installation plug-in and grafana image renderer
module ‘selenium. webdriver‘ has no attribute ‘PhantomJS‘
hands-on-data-analysis 第二单元 第四节数据可视化
[course assignment] floating point operation analysis and precision improvement
修修补补一时爽,果断重构有担当——聊聊CRM分布式缓存优化
哪个期货平台 交易更安全放心。求推荐。
Map collection traversal, adding, replacing and deleting elements
curl常用参数详解及示例
实践 DevOps 时,可能面临的六大挑战
TOOD: Task-aligned One-stage Object Detection
4. procedure flow structure
Babbitt yuancosmos daily must read: wechat may ban a official account for the first time on the grounds of "involving secondary transactions in digital collections", and the new regulations of the pla
Atguigu---- conditional rendering
[in depth understanding of tcapulusdb technology] tcapulusdb business data backup
618 Nuggets digital collection? Burberry and other luxury brands fight against metauniverse
Automatic operation and maintenance 2 - common modules in ansible
Kubernetes快速實戰與核心原理剖析
应用配置管理,基础原理分析
How to write test cases