この機能を設計するより良い方法は?
-
05-07-2019 - |
質問
主に、配列にデータを挿入する別の関数への大量の呼び出し(50+)で構成される関数があり、さまざまな項目を配列に挿入するさまざまな条件を指示するロジック(および少し)最後に、配列の内容をファイルに書き出します)。この関数を作成するより良い方法がないのではないかと思っています。配列挿入コマンドセットを論理的に独自の機能に分割することから始められると思いますが、他にできることがあるかどうか疑問に思っています。ありますか?
例:
function buildTable(fileName, data)
local dataToWrite = {}
table.insert(datTWrite, {
Type = "type1",
Key = "someKey",
Value = data.SomethingInteresting
})
--and so on ad nauseum with an occasional but of actual logic to spice things up
dataWriter:open(fileName .. ".bla")
dataWriter:batchWrite(dataToWrite)
dataWriter:close()
end
この場合、dataWriterは、ファイルへの書き込みプロセスを処理する定義済みクラスのインスタンスです。
解決
良いニュースは、出力を作成するためにループ内のバッファーに文字列を連結する一般的なLuaのペシマイゼーションに直接踏み込んでいないことです。
次のようにサンプルを作成します。
function buildTable(fileName, data) local t = {} t[#t+1] = { Type = "type1", Key = "someKey", Value = data.SomethingInteresting } --and so on ad nauseum with an occasional but of actual logic to spice things up dataWriter:open(fileName .. ".bla") dataWriter:batchWrite(t) dataWriter:close() end
一時テーブルにタイプミスを起こしやすい長い名前を使用しないという小さな利点があり、 t [#t + 1]
イディオムを使用して配列部分を拡張します。 table.insert()
を呼び出します。
それ以外の場合、構造的な改善の原因は、「広告の吐き気など」にあります。コードの一部。
- ローカル関数に収集できる一般的な計算とフラグメントを探してください。
- 関数定義をネストできることを忘れないでください。したがって、ヘルパー関数は、使用される場所にスコープを制限できます。
- あまりにも賢いロジックを探し、来年それを維持しなければならない人にとって賢明なロジックに書き換えます。
- wiki: Luaデザインパターン
- wiki: Zen Of Lua
- wiki:最適化のヒント
- wiki: Luaコードのプロファイリング
何よりも、早すぎる最適化に注意してください。比較のポイントとして現在持っているものをベンチマークし、パフォーマンスのボトルネックを見つけるためのガイドとして使用します。
他のヒント
"などにより、物事を盛り上げるための時々の、しかし実際の論理による吐き気」次のような多くのブロックがあることを意味すると思います:
table.insert(datTWrite, {
Type = "type1",
Key = "someKey",
Value = data.SomethingInteresting
})
この機能に固有の唯一の側面は、入力されるテーブルと data
オブジェクトです。私の個人的な「ベストプラクティス」このすべてを次のような別のテーブルに引き出します:
local entries = {
{
Type = "type1",
Key = "someKey",
ValueField = "SomethingInteresting",
},
{
Type = "type2",
Key = "someOtherKey",
ValueField = "SomethingElse",
},
-- etc.
}
このテーブルは、グローバルまたは関数が定義されている範囲外のスコープ内にある必要があります。これで、実際の作業を行う機能を変更することなく、エントリをより簡単に再構成できます。このようにエントリを反復処理することにより、関数自体が大幅に簡素化されます。
for i, entry in ipairs(entries) do
table.insert(datTWrite, {
Type = entry.Type,
Key = entry.Key,
Value = data[entry.ValueField]
})
end
「時々」の場合ロジックでは、各エントリにループ内の興味深い情報を提供するオプションの関数を含めることができます。例:
for i, entry in ipairs(entries) do
if not entry.CheckSomething or entry.CheckSomething() then
table.insert(datTWrite, {
Type = entry.Type,
Key = entry.Key,
Value = data[entry.ValueField]
})
end
end
別の方法として、さらにカスタマイズが必要な場合は、テーブル内の個々のエントリをBE機能にすることもできます。各エントリ関数はテーブルを返します(または返しません)。
for i, entry in ipairs(entries) do
if type(entry) == "function" then
local newEntry = entry()
if newEntry then
table.insert(datTWrite, newEntry)
end
else
table.insert(datTWrite, {
Type = entry.Type,
Key = entry.Key,
Value = data[entry.ValueField]
})
end
end
特別なことは何もせずに、コードのにおいを調べてみます関数がどのように比較されるかを確認してください。物事の音から、あなたがすべきことはおそらくたくさんあります。異なる条件ロジックによって分離された類似/コピーされたコードのブロックはありますか?ネストされたループまたは条件付き?これらは、大きな関数を部分に分割しようとするときの簡単な出発点です。