当前位置:网站首页>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 !
边栏推荐
- Kube Prometheus grafana installation plug-in and grafana image renderer
- 618 Nuggets digital collection? Burberry and other luxury brands fight against metauniverse
- [in depth understanding of tcapulusdb technology] tcapulusdb business data backup
- Pingcap was selected as the "voice of customers" of Gartner cloud database in 2022, and won the highest score of "outstanding performer"
- 8. structure
- 2. reference
- Web3.js connection to metamask wallet transfer
- MySQL - built in functions
- MySQL - transaction management
- 3. operator
猜你喜欢
JS 中的集合引用类型

TOOD: Task-aligned One-stage Object Detection

修修补补一时爽,果断重构有担当——聊聊CRM分布式缓存优化
MySQL constraints (descriptions of various conditions when creating tables)

CVPR2022 | 上科大x小红书首次提出动作序列验证任务,可应用于体育赛事打分等多场景

Work content of service governance

Use map set or list set to store list set

Must the database primary key be self incremented? What scenarios do not suggest self augmentation?

Eureka's timedsupersortask class (periodic task with automatic interval adjustment)

Navigation bar switching, message board, text box losing focus
随机推荐
SCCM creates a client collection based on the installed app and periodically pushes application updates
MySQL constraints (descriptions of various conditions when creating tables)
scrapy_ Redis distributed crawler
Consultation: what kind of securities company is micro securities? Is it safe to open an account?
Automatic operation and maintenance 4 - variables and encryption in ansible
MySQL - adding, deleting, querying and modifying tables
Two common schemes for handling interface idempotence
[deeply understand tcapulusdb technology] tmonitor system upgrade
【深入理解TcaplusDB技术】Tmonitor系统升级
Six possible challenges when practicing Devops
IMU selection, calibration error analysis, AHRS integrated navigation
Visualization strategy of Seaborn data overall distribution
Don't know how to interview? Test interview questions summary, teach you to face the interview questions
C language elementary level (10) type rename typedef
C language elementary order (VI) function
Kubernets Rapid Practical fighting and Core Principle Analysis
如何阅读AI顶会论文?
Memcached(高性能内存对象缓存)
MySQL - built in functions
Analysis on the wallet system architecture of Baidu trading platform