Показать сообщение отдельно
Старый 21.05.2018, 19:11   #1  
Blog bot is offline
Blog bot
Участник
 
25,459 / 846 (79) +++++++
Регистрация: 28.10.2006
erconsult: Internal iterator design pattern in X++
Источник: http://erconsult.eu/blog/internal-it...ern-in-d365fo/
==============

A couple of times in my carrier I stumbled upon a development requirement to perform a set of loosely connected actions with a similar interface upon a certain business object depending on entry conditions:
  • Sometimes do this
  • Sometimes do that
  • Sometimes do this and that
  • In future, you may do something else in addition.
In Dynamics 365 for Finance and Operations, this usually results in a hierarchy of classes. The classes are typically bound to some parameter table containing checkboxes or – better – an enumeration field. This enumeration directs a SysExtension class factory which classes to instantiate.
A simple while_select loop traverses the parameter table and executes the instantiated objects one by one. However, if the classes implement more than one action i.e. method, this external loop may become repetitive. I ended up with a certain design pattern which turned out to have a name in object-oriented programming: an internal iterator.
The constructor instantiates an object and gives it the previous one as a parameter, thus forming a linked chain of objects. The external actor only needs to take one parameter – the topmost object in the chain – and to call one operation .doThis() upon it. This .doThis() method is implemented in the parent class in the hierarchy, and the parent class knows how to traverse the objects.

Adding a new grid with a parameter table into an existing form is more difficult than adding new field(s) into an existing table via extensions. If the number of possible actions is countable and small, you may think of de-normalizing the parameter table and making an array field with possible options. Instead of iterating records, the constrictor will be iterating fields in one record.

Below is an application of this pattern to a simple task: calculation of the total nutrition value of one meal, while the meal may consist of an Entrée, and Entrée and a Main course, a Main course and a Dessert and so on:

class MealCourseAtrribute extends SysAttribute implements SysExtensionIAttribute
{
MealCourseEnum mealCourseEnum;
public void new(MealCourseEnum _mealCourseEnum)
{
super();
mealCourseEnum = _mealCourseEnum;
}
public str parmCacheKey()
{
return classStr(MealCourseAtrribute) + enum2Value(mealCourseEnum);
}
public boolean useSingleton()
{
return true;
}
}


abstract public class MealCourse
{
private MealCourseEnum mealCourseType;
private MealCourse prevMealCourse;
abstract protected MealKcal kcal()
{}
final public MealKcal kcalTotal()
{
MealKcal ret = this.kcal();
if (prevMealCourse)
{
ret += prevMealCourse.kcalTotal();
}
return ret;
}
private MealCourse prevMealCourse(MealCourse _prevMealCourse = prevMealCourse)
{
prevMealCourse = _prevMealCourse;
return prevMealCourse;
}
protected void new()
{
}
public static MealCourse construct(Meal _meal)
{
MealCourse mealCourse, prevMealCourse;
MealCourseAtrribute attr;
MealCourseEnum mealCourseEnum;
int i;
for (i = 1; i
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору.