コードの読み取り可能性-フォーマットとテスト
9482 ワード
テキストアドレス
読む順番は一般的に上から下へ、左から右へ縦フォーマット{:&.rollIn} 横フォーマット
距離のあるコードはこうです
距離がないと次のようになります
私もよくこのようにコードフォーマットの処理をします
間隔なし
複数の間隔
適切な間隔
このコードを見てみましょう
横間隔のあるコード
これらの横方向の間隔を削除
横の書式にスペースがあるべき場所(ここで黒板を強く叩く)演算子前後: 関数かっこ前: カンマの後: 解体: ……
[slide]
{:&.rollIn}
|利|弊:----------------------------------------------------------------------------------------------------------------------------------------------------------
完了
コード可読性
フォーマットとテスト
書式設定
コードを読むのは文章、小説、ニュースを読むのと同じです。
読む順番は一般的に上から下へ、左から右へ
縦書式
距離が美しい
距離のあるコードはこうです
…
const { UDFs, type } = this.props
const textFields = this.handleGroupByType('Text')
const numericFields = this.handleGroupByType('Numeric')
const timeFields = this.handleGroupByType('Time')
const datetimeFields = concat(this.handleGroupByType('Datetime'), timeFields)
const UDFsFunctions = sortBy(filterByUdfTypes(UDFs, [FUNCTION_TYPE_UDF]), UDF => UDF.name)
const UDAFsFunctions = filterByUdfTypes(UDFs, [FUNCTION_TYPE_UDAF])
const NORMALsFunctions = filterByUdfTypes(UDFs, [FUNCTION_TYPE_NORMAL])
const basicFunctions = isNotMetric(type) ? [...UDFsFunctions, ...NORMALsFunctions] : UDFsFunctions
const numericFunctions = filterByReturnType(basicFunctions, 'Numeric')
const textFunctions = filterByReturnType(basicFunctions, 'Text')
const datetimeFunctions = filterByReturnType(basicFunctions, 'Datetime')
const distinctUDAFs = uniqBy(UDAFsFunctions, 'name')
const aggregateFunctions = sortBy(distinctUDAFs, 'name')
const aggregateFunctionsFilter = filter(aggregateFunctions, aggregateFunction => aggregateFunction.tag != 'None')
return (
…
距離がないと次のようになります
…
const { UDFs, type } = this.props
const textFields = this.handleGroupByType('Text')
const numericFields = this.handleGroupByType('Numeric')
const timeFields = this.handleGroupByType('Time')
const datetimeFields = concat(this.handleGroupByType('Datetime'), timeFields)
const UDFsFunctions = sortBy(filterByUdfTypes(UDFs, [FUNCTION_TYPE_UDF]), UDF => UDF.name)
const UDAFsFunctions = filterByUdfTypes(UDFs, [FUNCTION_TYPE_UDAF])
const NORMALsFunctions = filterByUdfTypes(UDFs, [FUNCTION_TYPE_NORMAL])
const basicFunctions = isNotMetric(type) ? [...UDFsFunctions, ...NORMALsFunctions] : UDFsFunctions
const numericFunctions = filterByReturnType(basicFunctions, 'Numeric')
const textFunctions = filterByReturnType(basicFunctions, 'Text')
const datetimeFunctions = filterByReturnType(basicFunctions, 'Datetime')
const distinctUDAFs = uniqBy(UDAFsFunctions, 'name')
const aggregateFunctions = sortBy(distinctUDAFs, 'name')
const aggregateFunctionsFilter = filter(aggregateFunctions, aggregateFunction => aggregateFunction.tag != 'None')
return (
…
私もよくこのようにコードフォーマットの処理をします
import React from 'react'
import Radio from 'antd/lib/radio'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import Button from 'components/commons/Button'
import VirtualFieldDropDownMenu from './VirtualFieldDropDownMenu'
import VirtualFieldPreview from './VirtualFieldPreview'
import VirtualMetricPreview from './VirtualMetricPreview'
import Notification from 'components/Notification'
import Title from './Title'
import { insertField, insertFunction, filterByReturnType, filterByUdfTypes } from './virtualFieldService'
import isNotUndefined from 'utils/lodash/isNotUndefined'
import * as ReportActions from 'actions/report'
import * as DataSetFieldsActions from 'actions/dataSetFields'
import * as ReportSelectors from 'selectors/report'
import isUndefined from 'lodash/isUndefined'
import trim from 'lodash/trim'
import isEmpty from 'lodash/isEmpty'
import concat from 'lodash/concat'
import uniqBy from 'lodash/uniqBy'
import sortBy from 'lodash/orderBy'
import filter from 'lodash/filter'
import { FUNCTION_TYPE_UDF, FUNCTION_TYPE_NORMAL, FUNCTION_TYPE_UDAF } from 'constants/BindingItemsConstants'
import './VirtualField.styl'
適切な距離
間隔なし
handleAddNewUsers() {
const { newUsers } = this.state
if (isEmpty(newUsers)) return Notification.error(' ')
this.props.updateUsersInUserGroup(this.props.viewUserGroup.id, {userIds: newUsers}).then((response) => {
responseNotification(response, ' ')
this.setState({newUsers: []})
})
}
複数の間隔
handleAddNewUsers() {
const { newUsers } = this.state
if (isEmpty(newUsers)) return Notification.error(' ')
this.props.updateUsersInUserGroup(this.props.viewUserGroup.id, {userIds: newUsers}).then((response) => {
responseNotification(response, ' ')
this.setState({newUsers: []})
})
}
適切な間隔
handleAddNewUsers() {
const { newUsers } = this.state
if (isEmpty(newUsers)) return Notification.error(' ')
this.props.updateUsersInUserGroup(this.props.viewUserGroup.id, {userIds: newUsers})
.then((response) => {
responseNotification(response, ' ')
this.setState({newUsers: []})
})
}
このコードを見てみましょう
handleSaveReport({ name, directory, isSaveAsCopy }) {
const { workingReport, reportId } = this.props
if (isSaveAsCopy) {
const requestParams = saveReportCopyRequestParams(name, directory, workingReport)
this.props.createReportCopy(requestParams, this.state.directoryOfCurrentReport).then(() => {
Notification.success(' ')
this.setState({openSaveReportDialog: false, isSaveAsCopy: false})
}).catch((errors) => forEach(errors, error => Notification.error(error)))
} else {
const request = saveReportRequestParams(name, directory, workingReport)
this.props.saveWorkingReport(reportId, request, this.props.currentPageId).then(() => {
Notification.success(' ')
this.setState({openSaveReportDialog: false, isSaveAsCopy: false})
}).catch((errors) => forEach(errors, error => Notification.error(error)))
}
}
意見を修正する.
handleSaveReport({ name, directory, isSaveAsCopy }) {
const { workingReport, reportId } = this.props
if (isSaveAsCopy) {
const requestParams = saveReportCopyRequestParams(name, directory, workingReport)
this.props.createReportCopy(requestParams, this.state.directoryOfCurrentReport)
.then(() => {
Notification.success(' ')
this.setState({openSaveReportDialog: false, isSaveAsCopy: false})
})
.catch((errors) => forEach(errors, error => Notification.error(error)))
} else {
const request = saveReportRequestParams(name, directory, workingReport)
this.props.saveWorkingReport(reportId, request, this.props.currentPageId)
.then(() => {
Notification.success(' ')
this.setState({openSaveReportDialog: false, isSaveAsCopy: false})
})
.catch((errors) => forEach(errors, error => Notification.error(error)))
}
}
ポイントをつける(ここで黒板を強く叩く)
1.関連するコードを1つのブロックに配置し、他のコードブロックと空行で区切る(垂直方向の近接と距離)
2.垂直順序(上から下への表示関数呼び出し依存順序)
横書式
横の間隔と近接
横間隔のあるコード
const quarter = Math.floor((today.getMonth() + 3) / 3)
これらの横方向の間隔を削除
const quarter=Math.floor((today.getMonth()+3)/3)
演算優先度の強調
…
const XXX = (Math.…) + (a*2)
…
横の書式にスペースがあるべき場所(ここで黒板を強く叩く)
const view = this.props.view
handleChange() { … }
handleSave(arg1, arg2) { … }
['a', 'b', 'c']
const { id, name } = view
[slide]
{:&.rollIn}
フォーマット
テスト
関数の使用
describe('buildSelectorValue', () => {
it('should return new selector when oldSelectors is empty', () => {
const oldSelectors = {}
const originalSelector = buildOriginalSelector(1, [' '])
const exceptSelector = buildExceptSelector(1, [' '])
expect(buildSelectorValue(oldSelectors, originalSelector)).to.eql(exceptSelector)
})
})
定数の使用
it('should return selectors deleted by viewId', () => {
expect(deleteSelectorByViewId(twoViewsState, deleteSelectorViewId)).to.eql(oneViewState)
})
const deleteSelectorViewId = '1'
const twoViewsState = {
'1': {
pageId: 1,
dataSetId: 3,
values: [{
fieldId: 4,
selectorValues: [' ']
}]
},
'2': {
pageId: 1,
dataSetId: 3,
values: [{
fieldId: 4,
selectorValues: [' ']
}]
}
}
…
関数と定数の使用のメリットとデメリット
|利|弊:----------------------------------------------------------------------------------------------------------------------------------------------------------