By no means am I meaning to pick on @jkane but looking at his rather impressive widget usage here lead to me finally doing an analysis I’ve wanted to do for a long time regarding widgets vs code.
There have been a lot of discussions around here about whether widgets should be used and how often, when etc. so I decided to take a quick look for my own amusement.
I attempted to re-create a large widget Function and then do the same exact function without widgets. As examples goes it isn’t a great one, but it serves to illustrate the problem we are trying to solve is simple
- Retrieve a record from ABC Code using GetByID
- Assign 37 fields into this ABC Code record.
Widget:
Code It Generated 900+ LOC:
using Epicor.Customization.Bpm;
using Epicor.Data;
using Epicor.Hosting;
using Epicor.Utilities;
using Erp;
using Erp.Tables;
using Ice;
using Ice.Contracts;
using Ice.ExtendedData;
using Ice.Tables;
using Ice.Tablesets;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
namespace EFx.ButWhy.Implementation
{
partial class WidgetImpl
{
protected override int RunStep(int workflowStep)
{
var conditionBlockValue = false;
switch (workflowStep)
{
case Epicor.Functions.PredefinedStep.Start: // Invoke BO Method 0
try
{
this.A001_InvokeBOMethodAction2();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 1;
case 1: // Set Field 1
try
{
this.A002_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 2;
case 2: // Set Field 2
try
{
this.A003_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 3;
case 3: // Set Field 3
try
{
this.A004_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 4;
case 4: // Set Field 4
try
{
this.A005_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 5;
case 5: // Set Field 5
try
{
this.A006_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 6;
case 6: // Set Field 6
try
{
this.A007_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 7;
case 7: // Set Field 7
try
{
this.A008_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 8;
case 8: // Set Field 8
try
{
this.A009_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 9;
case 9: // Set Field 9
try
{
this.A010_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 10;
case 10: // Set Field 10
try
{
this.A011_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 11;
case 11: // Set Field 11
try
{
this.A012_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 12;
case 12: // Set Field 12
try
{
this.A013_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 13;
case 13: // Set Field 13
try
{
this.A014_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 14;
case 14: // Set Field 14
try
{
this.A015_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 15;
case 15: // Set Field 15
try
{
this.A016_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 16;
case 16: // Set Field 16
try
{
this.A017_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 17;
case 17: // Set Field 17
try
{
this.A018_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 18;
case 18: // Set Field 18
try
{
this.A019_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 19;
case 19: // Set Field 19
try
{
this.A020_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 20;
case 20: // Set Field 20
try
{
this.A021_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 21;
case 21: // Set Field 21
try
{
this.A022_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 22;
case 22: // Set Field 22
try
{
this.A023_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 23;
case 23: // Set Field 23
try
{
this.A024_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 24;
case 24: // Set Field 24
try
{
this.A025_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 25;
case 25: // Set Field 37
try
{
this.A026_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 26;
case 26: // Set Field 38
try
{
this.A027_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 27;
case 27: // Set Field 39
try
{
this.A028_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 28;
case 28: // Set Field 40
try
{
this.A029_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 29;
case 29: // Set Field 41
try
{
this.A030_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 30;
case 30: // Set Field 42
try
{
this.A031_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 31;
case 31: // Set Field 43
try
{
this.A032_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 32;
case 32: // Set Field 44
try
{
this.A033_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 33;
case 33: // Set Field 45
try
{
this.A034_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 34;
case 34: // Set Field 46
try
{
this.A035_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 35;
case 35: // Set Field 47
try
{
this.A036_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 36;
case 36: // Set Field 48
try
{
this.A037_SetFieldAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return Epicor.Functions.PredefinedStep.Exit;
default:
return Epicor.Functions.PredefinedStep.Unknown;
}
}
private void A001_InvokeBOMethodAction2()
{
this.CallService<Erp.Contracts.ABCCodeSvcContract>(
bo =>
{
System.String _arg01 = this.A001_InvokeBOMethodAction2_arg01();
ds = bo.GetByID(
_arg01);
});
}
[Epicor.Customization.CustomCode]
private System.String A001_InvokeBOMethodAction2_arg01()
{
return ("A");
}
private void A002_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A002_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A002_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A003_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A003_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A003_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A004_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A004_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A004_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A005_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A005_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A005_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A006_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A006_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A006_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A007_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A007_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A007_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A008_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A008_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A008_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A009_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A009_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A009_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A010_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A010_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A010_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A011_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A011_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A011_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A012_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A012_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A012_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A013_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A013_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A013_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A014_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A014_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A014_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A015_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A015_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A015_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A016_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A016_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A016_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A017_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A017_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A017_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A018_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A018_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A018_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A019_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A019_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A019_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A020_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A020_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A020_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A021_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A021_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A021_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A022_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A022_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A022_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A023_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A023_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A023_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A024_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A024_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A024_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A025_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A025_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A025_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A026_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A026_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A026_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A027_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A027_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A027_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A028_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A028_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A028_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A029_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A029_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A029_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A030_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A030_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A030_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A031_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A031_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A031_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A032_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A032_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A032_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A033_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A033_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A033_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A034_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A034_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A034_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A035_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A035_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A035_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A036_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A036_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A036_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
private void A037_SetFieldAction()
{
var query = ds.ABCCode.Where(row => !row.Unchanged());
foreach (var item in query)
{
item.ABCCode = this.A037_SetFieldAction_ABCCode(item);
}
}
[Epicor.Customization.CustomCode]
private System.String A037_SetFieldAction_ABCCode(Erp.Tablesets.ABCCodeRow item)
{
return ("A");
}
}
}
Non Widget Method:
Code It Generated 118 LOC:
using Epicor.Customization.Bpm;
using Epicor.Data;
using Epicor.Hosting;
using Epicor.Utilities;
using Erp;
using Erp.Tables;
using Ice;
using Ice.Contracts;
using Ice.ExtendedData;
using Ice.Tables;
using Ice.Tablesets;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
namespace EFx.ButWhy.Implementation
{
partial class WidgetFunctionImpl
{
protected override int RunStep(int workflowStep)
{
var conditionBlockValue = false;
switch (workflowStep)
{
case Epicor.Functions.PredefinedStep.Start: // Invoke BO Method 0
try
{
this.A001_InvokeBOMethodAction2();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return 1;
case 1: // Execute Custom Code 0
try
{
this.A002_CustomCodeAction();
}
catch (Ice.Common.BusinessObjectException ex)
{
this.RememberException(ex);
}
return Epicor.Functions.PredefinedStep.Exit;
default:
return Epicor.Functions.PredefinedStep.Unknown;
}
}
private void A001_InvokeBOMethodAction2()
{
this.CallService<Erp.Contracts.ABCCodeSvcContract>(
bo =>
{
System.String _arg01 = this.A001_InvokeBOMethodAction2_arg01();
ds = bo.GetByID(
_arg01);
});
}
[Epicor.Customization.CustomCode]
private System.String A001_InvokeBOMethodAction2_arg01()
{
return ("A");
}
[Epicor.Customization.CustomCode]
private void A002_CustomCodeAction()
{
foreach (var x in this.ds.ABCCode.Where(row => !row.Unchanged()))
{
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
x.ABCCode = "A";
}
}
}
}
Neither of these options is particularly elegant, but here’s a breakdown of their Big O efficiency/complexity metrics along with other relevant considerations. Big O complexity is a way to describe how the performance or scalability of an algorithm changes with input size.
Big O Categories:
-
O(1) – Constant Time:
This means the algorithm’s performance does not depend on the size of the input—it runs in the same amount of time regardless. For example, a function likeGetDateTime()
always returns the current date and time in constant time, whether today, tomorrow, or next year. -
O(n) – Linear Time:
Performance scales directly with input size. The larger the input, the longer the algorithm takes. For instance, a counting loop:
CountTo(10); // Takes less time
CountTo(100); // Takes 10x longer -
O(n²) – Quadratic Time:
Here, performance scales exponentially with input size. For example, a standard sorting algorithm might iterate through a list multiple times, resulting in a time complexity proportional to the square of the input size. Doubling the input roughly quadruples the work.
Aspect | Code | Widget |
---|---|---|
Number of Dataset Iterations | 1 (single pass through ds.ABCCode ) |
(m) (one pass per field, (m = 36) in this case) |
Number of Assignments | (n * m) (all fields assigned in one loop) | (n * m) (one assignment per iteration per field) |
Number of Methods Invoked | 2: A001_InvokeBOMethodAction2 , A002_CustomCodeAction |
(2 + m): A001_InvokeBOMethodAction2 + (m) field-specific methods |
Code Jump Points | Minimal: 1 return per switch case | High: (m) return points, one for each field-specific case |
Workflow Complexity | Simple: Linear execution through 2 steps | High: Linear execution but with (m) additional workflow steps |
Big-O Complexity (Dataset) | (O(n)) | (O(n * m)) |
Big-O Complexity (Workflow) | (O(1)): Workflow has minimal state transitions | (O(m)): Workflow has (m) transitions |
Overhead per Field Update | Minimal (loop runs once, condition per field) | High (new loop and query per field update) |
Code Reusability | Moderate: Harder to reuse logic across fields | High: Field-specific logic encapsulated in methods |
Code Maintainability | Low: Single large method harder to debug | High: Modular field-specific logic improves clarity |
Readability | Moderate: All logic in one place but harder to trace specific fields | High: Clear separation of logic per field |
Testing Simplicity | Low: Harder to isolate and test individual fields | High: Easy to test/update individual field logic |
Anyway I’m not necessarily arguing one way or another and I don’t want to get into another religious war It was mostly morbid curiosity. But here are some of my own observations.
- Code First processes the dataset in a single pass, reducing iteration overhead, while Widget First iterates once for each field update, increasing execution time with each individual widget at a rate of m*n (once per widget)
- Widget First is more modular, with each field update encapsulated in its own method, making it easier to debug or extend compared to the centralized logic in Code First. However this is abstracted to us by the software
- Code First minimizes the number of function calls, while Widget First has a higher number of method invocations due to its field-specific design and a billion return points leading to some nice spaghetti code (which is admittedly abstracted by the software)
- Code First scales better with an increasing number of rows in the dataset
- Workflow complexity is minimal in Code First with fewer jump points, whereas Widget First has higher complexity due to many workflow steps and returns.
- Code First provides significantly better performance but you sacrifice the ease of maintainability by having to write code.
- Widget First Generated over 900+ LOC more isn’t always better
- Widget First 118ish+ LOC Less isn’t always better, more compact code generally means more inherit complexity in a single method.
I guess what I am trying to illustrated is that while yes Widgets can be convenient you are sacrificing efficiency in some cases. Similarly by writing a bunch of code you may be making a more efficient BPM or Function but you are sacrificing maintainability. So Right tool for the Right Job.
As Confucius said “Do not use a cannon to kill a mosquito.”