ABS Framework - Prototype Library

[What is a Prototype?]

Using the prototype object is common in web development circles, but it is foreign to most experienced Siebel professionals.

This is the definition of “prototype” object according to Siebel Help
    An object prototype lets you specify a set of default values for an object. When an object property that has not been assigned a value is accessed, the prototype is consulted. If such a property exists in the prototype, its value is used for the object property.

    Object prototypes are useful to be sure that every instance of an object use the same default values and that these instances conserve the amount of memory needed to run a script. Then every instance of the object use the same function instead of each using its own copy of it.


That is quite an abstract description, and although it tries to explain the concept using a generic example, it still feels very disconnected.

In layman terms, using the prototype statement allows developers to add properties and methods to all instances of custom and pre-built objects in eScript/browser script (excluding Siebel Objects).

    So how do we use prototype to solve real world Siebel problems?

[ABS Prototypes]

The ABS framework includes prototypes to reduce the daily scripting chores for Siebel professionals. In this article we look at the some of the most interesting prototypes in ABS, and see how it can make our lives easier and more fun.

The ideas for these prototypes comes from years of experience and tideous hours of work to encapsulate the common routines that Siebel configurators and Integration people can share in one common library.

Array.IsIn

There are a lot of times when we want to compare the current active view, to a list of predetermined views, before performing some action.

Normally we have to write code like this to achieve it

var sViewName = TheApplication().ActiveViewName();

If (sViewName == “View1” || sViewName == “View2” || sViewName == “View3”) {

}

ABS provides us with IsIn() to achieve this same functionality in a more elegant manner.

var aViewName = [“View1”,“View2”,“View3”];
if (aViewName.IsIn(TheApplication().ActiveViewName()) {
}


This function returns a Boolean, indicating whether a value exists or not, but also returns an additional property that points to the index of the matched value.

Date.ToISO

ToISO() is useful for formatting dates to ISO format. This is commonly used to convert dates, so it can be easily sorted alphabetically.

var oDate = new Date(2000,1,1);
oDate.ToISO() = "20000101"


Date.ToDB

ToDB() allows the developer to get the current date and do a setfieldvalue without doing messy conversions.

Date.ToDB() //This returns the current date in MM/DD/YYYY format for setfieldvalue


Date.Compare
Compare() is a really powerful shorthand method of comparing dates or datetime.

A common business requirement is to ensure the currently selected date is greater than the created date, but less than a future date.

Heres how we would normally perform this operation.

//Convert to date object
oCreated = new Date("12/31/1999");
oFutureDate = new Date("1/1/2001");
oCurrentDate = new Date("1/1/2000");

If (oCurrentDate.GetTimeStamp() > oCreated.GetTimeStamp() && oCurrentDate.GetTimeStamp() < oFutureDate. GetTimeStamp ())


ABS does it in one line

Date.Compare("1/1/2000",">","12/31/1999","<","1/1/2001") = true


Heres a couple more examples of how it can be used to quickly compare dates.

//Created for date comparison of date1>date2 or date1>date2>date3
//Example 1:
Date.Compare("12/31/1999",">","1/1/2000") = false

//Example 2:
Date.Compare("12/31/1999","<","1/1/2000",">","") = true
//for the case of open date


Array.PSToStr

PSToStr () converts a Siebel PropertySet to a string for debugging. This is a very common situation for developers to find themselves in.

But it’s the implementation of this function as part of the Array object, which makes it unique. This allows it to be executed from Global scope, anywhere in the application, without using business service script libraries.


var oPS = TheApplication().NewPropertySet();

oPS.SetProperty(“A”,”1”);
[oPS].PSToStr(); //This returns a string representation of the PS


[Reducing code in your application]

Date.Compare() is a really good example of how prototypes can reduce code in your application. This prototype allows a developer to use date strings, to compare dates, without having to manually convert them to date objects.

Converting strings to dates is integral to comparing Dates correctly in Siebel, so instead of having these date conversion routines littered across the application in BCs, Applets and BSs, ABS prototypes this functionality to the Date Object.

ABS Prototypes is a feature purely for coders, but even if you don’t write a lot of script, whatever script you write will be very compact.

What if your project has massive amounts of scripting? We all know these projects exist.

Some projects start off with the noble principle of “exhausting” every declarative means of configuration, before turning to script, but this usually dosnt last, and there are a few common reasons for this.

    * Project cannot say “No” to funky ideas from business
    * Tight deadlines
    * In-experienced developers


Its likely to be a combination, if not all of the above. Its natural that people pick up scripting quicker than using WF, a junior can come in fresh from high school, know a little bit (or a lot) of Javascript, copy a bit of code from here and there, and with a small amount of effort, get a working solution.

Using prototype allows projects to build your own code library, these functions are bound to the standard ECMA objects, and can be re-used across the application without instantiation.

[Reduce memory usage]

I know you didn’t pay much attention to Siebel’s definition of prototype, but its interesting to revisit it (a part of it).

    Object prototypes are useful to be sure that every instance of an object use the same default values and that these instances conserve the amount of memory needed to run a script. Then every instance of the object use the same function instead of each using its own copy of it.


At this stage, we have a little more context of what prototype can do for our projects, and the Siebel definition seems to be more comprehensible.

But for the project managers, and executives out there, the prototype objects ensure that functions are instantiated once and shared across the application, and by taking advantage of prototypes, a project can reduce the memory usage in the application.

With a robust suite of prototypes at the core of your application, you have a more scalable and manageable solution at hand.

[Conclusion]

The ABS Prototype feature, dosnt make people better scripters, but it does reduce the amount of scripting in the application, and provides a repository of common routines, that in-experienced (and experienced) developers can rely on, without re-inventing the wheel.

Benefits of using Prototypes


    1) Reduce the size and clutter in the repository
    2) Reduce redundant code writing
    3) Standardize implementation of common routines
    4) Easier code maintenance
    5) Speed and streamline up code development
    6) Reduce memory usage


Pre-requisites


Prototypes should be implemented by developers with a solid understanding of ECMA script (not eScript). Improper implementation of prototypes can lead to memory leaks and defective behaviour across your application.

This also applies to projects that currently have ABS, and want to enhance the prototype library.

Projects need to ensure that there is a clear owner for the prototype library, and this person or group, have exclusive controls to these library functions, and makes changes on behalf of everyone. This ensures a layer of quality control, and a consistent coding standard is maintained for the project.


8 comments:

  1. Any idea how Object inheritance works in the ST engine?

    ReplyDelete
  2. Can I know where I can access the ABS framework? Is the prototype library included as part of Siebel 8.0 or later versions? Any help on this regard is appreciated.

    ReplyDelete
  3. Hi Narayan,

    The ABS Framework is proprietry, it is not shipped with any version of Siebel. You need to be on a project that has ABS to access it.

    ReplyDelete
  4. I've been doing some of my own tinkering trying to see if I can recreate some of the effects and benefits of the framework as I see them - I've had some success so far, as well as some head-scratching!

    This line intrigues me: [oPS].PSToStr();

    Ok - to me this looks like it creates an Array object, which would have the propertyset as a member. PSToStr is being invoked on the Array object - so I assume a function has been added to the Array's prototype using Array.prototype.PSToStr = function () { ... } or perhaps to the Object object's prototype. This seems to follow what you're suggesting anyway.

    Am I in the right ball park?

    The problem I've found with this approach (or indeed, trying to add any custom methods to either the Array or Object's prototype is that when you try to get at the Array members using "in":

    var mycars = new Array(");
    mycars[0] = "Saab";
    mycars[1] = "Volvo";
    mycars[2] = "BMW";

    for (x in mycars)
    {
    // do something with mycars[x]
    }

    The method we've added using the .prototype shows up as a member also!

    Any thoughts?

    ReplyDelete
  5. Hi Matt

    [oPS] creates an array object with oPS as the first element. PSToStr returns a string representation of the PS.

    The for in loop is used for object or associative array iteration. If u have a reason to use this on numerical arrays, u can filter out custom properties using the hasOwnProperty method, but this only works under the T engine.

    ReplyDelete
  6. MattW, as Jason wrote, by using "in", you are accessing all properties of that object. You will get array's "length" property too. You must filter all non numerical indexes. Your approach is good when you know that there can be large gaps between indexes.

    ReplyDelete
  7. While starting from scratch and understanding that objects are different from arrays and the "correct" use of the "in" statement one thing, when trying to add these features to well established code you may find the use of "in" to iterate through arrays. Rather than rewrite all the code I'd rather avoid adding any custom methods to Array.prototype (and also Object.prototype) for this reason. I don't think I've seen any code that *has* to be in either (but am open to examples!)

    Take the IsIn example mentioned: a method "inList" could be writen into String.prototype that takes an array as it's input - so to see if "Hello" is in the list "Hello", "Goodbye":

    "Hello".inList(["Hello", "Goodbye"]); // true
    "Hello!".inList(["Hello", "Goodbye"]); // false

    Personally, I think this reads a little better than the IsIn example.

    For the PS method, while interesting, again I don't see a compelling reason for it being essential to be added to the Array.prototype - I think this could just as easily be added to a Utility class in the Framework, or a Service class (to encapsulate functionality relating to Business Services) - a slightly more logical grouping than being a member of the Array class perhaps?

    ReplyDelete
  8. Hi Matt,

    Before implementing prototypes, i recommend your project engage an architect that specialises in eScript to design your script library. Since the script library will be a core part of your application, it needs to be robust, improper implementation of prototypes in eScript can lead to memory leaks.

    IMHO i wouldnt design a framework to meet the standards of existing code, the existing code should be re-written to utilise the framework.

    ReplyDelete

Comments are open to all, please make it constructive.