Salesforce はマルチテナント型の SaaS のため、特定の顧客がリソースを食い潰さないように、ガバナ制約
を設けています。
Apex によるカスタム開発を行う際は、常にこの ガバナ制約
を意識して記述する必要があります。
また、レコードの Id の扱いにも要注意です。
これらを前提とした開発を行うために、本記事ではいくつかのアンチパターンと、その回避方法を紹介します。
アンチパターン:ループ内のDML操作
Apex コードでループ(for文など)内に DML操作
(insert, update, delete, upsert)を配置することは、真っ先に覚えるべきアンチパターンです。
各繰り返しでデータベーストランザクションが発生し、ガバナ制限に達するリスクが高まるためです。
悪い例
for(Account acc : accountList) {
// ループ内でDML操作
update acc;
}
良い例
コレクション(ListやMapなど)を使用して、ループの外で一括DML操作を行います。
List<Account> accountsToUpdate = new List<Account>();
for(Account acc : accountList) {
// 必要な変更を加える
accountsToUpdate.add(acc);
}
update accountsToUpdate; // ループ外で一括DML操作
アンチパターン:ループ内でのSOQLクエリ実行
これも前章の内容と同様です。
ループ内でSOQLクエリを実行すると、各繰り返しでクエリが実行され、ガバナ制限に達するリスクが高まります。
これは非効率的でリソースを浪費する行為です。
悪い例
for(Contact con : contactList) {
Account acc = [SELECT Id, Name FROM Account WHERE Id = :con.AccountId];
// 何らかの処理
}
良い例
事前に必要なデータをクエリし、ループの外でデータを処理します。
または、Mapなどのコレクションを使用して関連データを効率的にアクセスします。
Map<Id, Account> accountMap = new Map<Id, Account>([SELECT Id, Name FROM Account WHERE Id IN :accountIds]);
for(Contact con : contactList) {
Account acc = accountMap.get(con.AccountId);
// 何らかの処理
}
アンチパターン:ハードコーディングされたID
システムの各種ID(オブジェクトのレコードIDや各種設定のID等)は、環境が変わる(例えば、 Sandbox から本番環境への移行)ごとにIDが変わります。
これらをハードコーディングすると、意図しない不具合を生む原因となります。
代わりに、動的にIDを取得する方法を使用するべきです。
「本番環境ではこの ID だから大丈夫」 は、ただの言い訳です。絶対にやめましょう。
Salesforce 環境の引っ越しをするときに絶望しますよ。
悪い例
String recordTypeId = '012000000000123'; // ハードコーディングされたレコードタイプID
Account acc = new Account(Name='Sample', RecordTypeId=recordTypeId);
// 後続処理...
良い例
// レコードタイプIDを動的に取得
Schema.DescribeSObjectResult accDescribe = Account.SObjectType.getDescribe();
List<Schema.RecordTypeInfo> accRecordTypes = accDescribe.getRecordTypeInfos();
for (Schema.RecordTypeInfo rtInfo : accRecordTypes) {
rtInfo.getRecordTypeId();
}
// 後続処理...
※例外的に、レコードタイプの ID は、本番環境からリフレッシュした Developer Sandbox でも値は同じです。が、それでもハードコードはやめましょう。
おわりに
Salesforce の Apex 開発における一般的なアンチパターンと、それらを避けるための実践的な回避方法を紹介しました。
開発者として、これらのパターンを認識し、適切な設計とコーディングプラクティスを適用することで、より効率的で保守しやすいコードを書くことができます。
一時の気の迷いで、負債を残すのはやめましょうね。
コメント