Calculating the workload for speech language pathologists is a very complex process. A systematic approach has to be developed in order to calculate the workload and to setup a standard. A workload analysis system is to be developed in order to meet the needs of school settings of calculating workload. The workload analysis system allows school districts to calculate budgets for speech language services and to assign adequate workload for speech language pathologists.
In school settings, speech language pathologists (SLP) often have a huge caseload. The whole process of calculating the workload is very complex. The objective of this project is to systematically analyse the process of calculating the workload and setup a standard. According to the position statement of the American Speech and Hearing Association (2002), the term caseload refers to the number of students that school SLPs directly serve student. In contrast, the term workload refers to all activities required and performed by the SLPs. The difference between caseload and workload makes it very difficult to come up with a standard to calculate workload. In order to meet the needs of calculating workload for school based SLPs, a rules engine system has to be developed to analyse the workload for school SLPs. The basic criteria for workload calculation are as follows:
- When a student (patient) is added to the caseload, the SLP has to spend time not only for direct or indirect services and evaluations, but also for mandated paperwork, multidisciplinary team conferences, parent and teacher contacts, and related responsibilities.
- Caseload must be a size to allow SLPs to provide appropriate and effective intervention.
Schools must implement a workload analysis approach to setting caseload standards in order to allow SLPs to engage in the broad range of professional activities necessary to meet individual student needs.
In the meanwhile, a workload analysis system is necessary in order to calculate not only individual workload, but also budgets. The system can be tailored to meet the needs of every school district. In addition, the principal can use the system to calculate budgets for speech language services. By using the workload analysis system, the school district can make sure that their speech language pathologists can have a reasonable workload and also students can receive adequate services.
The system will be designed and implemented by using a standard three tier architecture and the .NET 2.0 Framework. Based on a logical 3-tier application, I can gain the following advantages: Encapsulate and centralize all the business classes into a .NET assembly that is easy to create, use, and re-use. It helps me to maintain the code easier. The database access class is separated as an individual .NET component so the front-end code does not have SQL embedded in it. The 3-tier architecture also provides the flexibility to separate components to integrate with other components. This helps with scalability and better centralization of code. (Sheriff , P. D., 2002). The .NET 2.0 Framework is the programming model for the .NET platform which is developed by Microsoft. There are two major components inside the .NET Framework: one is the Common Language Runtime and another is the .NET Framework Class Library. The .NET Framework Class Library provide rich assembly components, including ADO.NET, Windows Forms, and other DLLs. The .NET Framework is a managed execution environment. It helps the developer to simplify development and deployment. It also integrates with a wide variety of programming languages such as VB.NET, C++, C #... (Microsoft .NET Framework, 2006).
In my Workload System, the first tier is the presentation tier. In the first tier, the Windows Form can be used to accept all inputs from the user. Behind the Windows Form, the VB.NET class will handle the form event calls to talk with the business objects, which is my second tier. All my business objects will be sit in the second tier. In the second tier, the rules engine component can also be laid to be interactive with the business object. The third tier will include all my data access lasses. The domain design pattern can be applied for the data access layer. See Figure 1.
Analysis of the Workload System
Once I have the basic idea about the system, I can see there are a couple of major problems I need to spend my effort to analyze and find the solution for the workload system.
The business objects will be the core components of my system since I design my application based on object-oriented concepts. All the business objects will be centralized into a separate layer.
For each business entity, there will be a .NET class object created to represent it. In each object class, all the private data will be addressed by the public property field which can be accessed from outside the class. An interface (
IData) will also be defined.
IData should include all the database functional calls. Such as Insert, Update, Delete, and Select. Once a business object inherits the
IData interface, it will be enforced to provide the database method implementations. The
IData interface provides the ability for the business object to talk with the data access objects. However, the business object should not only contain data, but also define all the business functions along with that data. All the work from the Windows Form UI can only be transferred to the database by calling the business object.
In order to track whether the business object data has changed or not, I would like to introduce a
DataChange event. The
DataChange event will be raised whenever the data changes from the Windows Form. Once the
DataChange event is fired, it will call the rules engine to start validating the business object.
As I said earlier, most of my business objects will be data related. The UI can just interact with the objects to manipulate the data. Therefore, the object-in-charge concept will be applied through the whole system. The class itself should know how to create an instance of itself. For instance, I have a class called
SLP (Speech Language Pathologist). I can simply using the New key to create a new
SLP object when the Supervisor clicks a new SLP button to create a new SLP from the Windows Form. Although no information about the new SLP has been input from the Supervisor yet, the
SLP class will create an SLP by default which is ready to be used during the creating process. Example:
Dim oSLP as New SLP()
Within the object’s constructor, I write the code to contract the instance of
SLP with database by using the
SetDefaultSLP() method and set the returning primary key back to the SLP
ID property. I actually bind an SLP database record with an
SLP instance through
SLP’s primary key. Example:
Public Sub New()
Me.ID = SetDefaultSLP()
Because the SLP class implements the
oSLP will easily accept all the database Select, Update, and Delete method calls to implement and update itself to the database.
A significant problem I am facing is translating the relational database data into an object model for processing all the business demands whenever it is called, and then changing it back to the relational model SQL Express database once it finishes business processing. In order to solve this problem, I would like to combine the object model and relational model together to the business class. All the data will be stored as a property along with the object. Object behaviors will be implemented through the methods. For example, the patient object has Age, Type, Sex properties to hold the data.
SelectPatient (patientID) is the behavior of the patient. Once
SelectPatient (patientID) is called, it will call a Store Procedure to retrieve all the information from the database related with passing the
patientID. A .NET
DataRow object will be returned back. For each field inside the
DataRow object, assign the value to the corresponding properties. Example:
Dim oPaitient as New Patient
Private _age as integer
Public Property Age() As Integer
Set(ByVal Value As Integer)
_age = value
Public Sub SelectPatient(byval patientid as integer)
Dim dr as new datarow
dr = getPatient(patientid)
for each field in dr
Me.Age = dr(“Age”)
Me.Type = dr(“Type”)
Although I define all my business objects as an individual class in my business logic layer, I still see that there are some common fields that can be shared among some objects which I need to store to the database at one time or another. For instance,
Supervisor are both business objects in the system. They both can belonge to the
Employee type in the school or rehab center.
Patient (students) is another business object type in the system. They are all related in some sort of work with people. As a person type, the three classes have some common field, such as person’s ID, Name, DOB, Age… Therefore a
Person base class can be used for some default implementations for the
Patient classes. On the top level, I define the
Person class as a base class. The
Person class provides
DisplayName with the default implementation. The
CalculateAge method in the
Person class will assign the
Age property based on the person’s DOB. There is a polymorphic behavior in the person class for
DisplayName. By default,
DisplayName will concatenate only the person’s first name and last name and return it as their full name. The
Employee class inherits from the
Person class and overrides the
DisplayName method to concatenate the title as a part of the names. The
SLP class inherits from the
Employee class and overrides the
DispalyName method by adding the employee ID instead of the title. The
Patient class also inherits from
Patient needs to concatenate the room number in front of the name to override the default
DisplayName method in the
Person class. Example:
Public MustInherit Class Person
Pubic Function CalculateAge() as integer
Assign the Age base on the DOB
Public Overridable Function DisplayName() as String
Return firstname + lastname
Public Class Employee
Public Overrides Function DisplayName() as String
Returntitle + firstname + lastname
Public Class Patient
Public Overrides Function DisplayName() as String
Returnroomnum + firstname + lastname
Public Overrides Function DisplayName() as String
Returnemployeeid + firstname + lastname
....use DisplayName from employee class
Public Overrides Function DisplayName() as String
From the above structure, I not only took advantage of the object-oriented concept of inheritance, but also used the polymorphism property for all my subclassed by optionally overriding
DisplayName from the base class.
Rules Engine Component
Besides the business objects, the rule engine is another key component for the work load system. One of the workload system’s goals is to simplify the tracking of broken business rules and evaluate the SLP’s workload based on the assigned patient’s conditions. Example:
- One workload calculation must and only can have one SLP
- One SLP at least has one patient assigned
- Total points of workload has to be a positive number
- DOB must be date format
Formulas based on the patient’s condition:
- No direct service-3
- Academic support needs + 5
- Mild articulation only-1
WorkLoad is the biggest object which is created and utilized for the entire process. The
WorkLoad object contains other objects, such as
Patient… In order to provide business rules checking, each
WorkLoad object will have an associated collection list of the current broken business rules. Since it is a rule checking process, only a boolean value can be returned to indicate whether the business requirement was met for the incoming
WorkLoad object. If the result is false, that problem description of the rules for the invalid fields or requirement will be stored in the broken rule collection list and displayed to the user.
To calculate the workload points based on the formula, I use the same approach. In the
WorkLoad object, a
totalWorkLoadPoint property is associated to record the workload points after the incoming workload is digested from the rules engine. I will discuss the algorithm the rules engine uses to check with the workload object when I analyse how to integrate the rules engine component with the business object section.
All the workload objects will use the same rule engine to validate and evaluate the rules and formula again and again. Therefore the rules engine component can be a static process existing in the entire workload application domain. For thread safety aspect, I think the singleton pattern will suit the requirement. Only one instance will be created at the beginning of the rule engine component load. In the rule engine class, the
GetRulesEngine method always checks if a rule engine instance has been initialized. If yes, use the existing rule engine instance, else create a new instance for the rule engine class. Example:
Public Class RulesEngine
Private Shared singleRulesEngine As RulesEngine
Public Shared Function GetRulesEngine() As RulesEngine
If singleRulesEngine Is Nothing Then
singleRulesEngine = New RulesEngine()
In the rule engine component, the rules set class can be declared to represent all the business rules and the formulas. All the business rules and formulas will be stored in a SQL Express 2005 database by running a SQL script as part of the installation process for the workload system. The rules set class will load all the rules and formulae whenever the rule engine is called the first time. Each rule record can be represented as a single instance of the
RulesSet class. In the rule engine class, a collection dictionary caches all the rules during the process.
Public Class RulesSet
Public Class RulesEngine
Public Shared Property RuleSetCollection() As Dictionary(Of Integer, RuleSet)
If RuleSetCollection Is Nothing then
ReturnRuleSetCollection = LoadRuleSet
RulesSet class, the formula is the hardest part to declare and implement. What I probably will do is define all the formulae as Regular Expressions which can be read from the .NET 2.0 built-in Regular Expression library. There is a
Match method in the Regular Expression class that may help me to take a text as an input string and process it to challenge the provided expressions.
Public Class RulesEngine
Public Function Evaluate (ByVal rule.formula As String, _
ByVal toEvaluate As String) As Boolean
Dim mRegExp As Regex
Try mRegExp = New Regex(rule.formula)
If mRegExp.IsMatch(toEvaluate) Then
Catch exp As Exception
Return "Exception occured:" & exp.ToString()
mRegExp = Nothing
End Try End Function
Evaluate method will complete all the business rules and formula validations based on the result returned from the evaluation process. If it fails the business, the rule’s description will be added to the workload broken rule collection list and returned to the user. If it passes the formula, then
workLoadPoint will be added to the
totalWorkLoadpoint for the incoming workload object.
Integrate the Rules Engine Component With Business Objects
After I have my business objects and rules engine ready, the next challenge is how to make them work with each other. First I would like to point out that all the rules and formulae will apply only to the object properties. That is the reason that I defined
FieldToValidate from my previous
FieldToValidate is the field I actually need to validate for my runtime business object, therefore the description in
FieldToValidate needs to follow the same structure the business class has. For example, in one of my
WorkLoad objects, I have an SLP associate. In the
SLP object, there is a
HiredDate field that has to be the
Date type in my business rule definition list (see Figure 3).
FieldToValidate needs to reflect the corresponding business object property so I will put the following structure to
FieldToValidate for the
HireDate business rule (see Figure 4).
The advantage of doing it this way is from the
FieldToValidate contents I can easily find out which property the rules engine seeks to evaluate by the specific business rules. Once I know the field, then I think the Reflection class from the .NET Framework can help me to retrieve the current object property value at runtime when I need to validate the business rules. The value I retrieve from the runtime object and the formula can be passed as the Regular Expression string (input string) and the Regular Expressions (rule) to
Evaluate to be validated. The following algorithm analyses the working procedures when the rules engine is called to evaluate the workload object. It may help us understand the entire evaluation process.
- Receive a
- Extract the current
WorkLoad object based on the required fields which have to be validated. All non-check business rule fields will be removed.
- Pass the extracted
WorkLoad to the rules engine.
- Rule engine loads all the rules and caches them in
RuleSetCollection which is a dictionary list the first time.
- Loop through each rule.
- For each rule:
For date, the
- 6.1 Retrieve the value based on the
- 6.2 Evaluate the retrieved value with the formula expression.
- 6.3 Check the precondition (exit if it’s not true).
- 6.4 Check the formula if the precondition is true.
- 6.4.1 For rules type: Add rules to the broken rule list if the result is false.
- 6.4.2 For formula type: Add
totalWorkloadPoint if the result is true.
WorkLoad broken rule list and
Each rule should have two conditions associated with it: Condition and Precondition. Condition is the major rule that needs to be directly validated. Precondition is a pre-requirement associated with that rule. Only after the precondition is validated can the condition start validating. For instance: a patient needs Academic Support Needs. The pre-condition for this rule is the patient is a student. Therefore, the rule engine will load the
patienttype to check if this patient is a student or not. Therefore, the Academic Support Needs rule is only checked when
student. If a rule requires more than one pre-condition, then the Regular Expression provides a way to concatenate two pre-conditions together as one pre-condition. All the rules are very straightforward and associated with all the business object property attributes. Therefore, all conditions and preconditions will only depend on the object’s property checking and return a boolean value. No rules rely on other rules; each rule should clearly address one specific condition, no rules interaction scenarios will be considered at the design phase for the system at this time. After integrating the rules engine and the business, whenever a field is changed or updated, the business object can also immediately get updated for the broken rule list and the
totalWorkLoadPoint. Since all the rules will be manually created at the beginning of the installation by running a database script, all the rules should exist in the database so that the user can not modify them at this time. I may create another Windows Form that allows the user to maintain and update all the rules directly from the tool if the rule-update scenario happens more often.
Transfer the Data from the Business Layer Through the Data Access Layer
The database layer is like a bridge layer to save all my business objects to a relational database. Fortunately the ADO.NET already provides set of classes to expose data access services to the .NET programmer. I only need to develop all the data actives by calling the stored procedures, which is simple. When the business class implements the IData interface, it will provide database method call for that class. One of the big advantages of object-oriented programming is to encapsulate all the functionality as one assembly and plug into with other project. In order to save my work I will go with Microsoft DataApplicationBlocks.Accordingto Microsoft official web site “The Data Access Application Block is a .NET component that contains optimized data access code that will help you call stored procedures and issue SQL text commands against a SQL Server database” (Microsoft, 2006). By borrowing the existing Data Application Block, I definitely save plenty of time for all my data access work in this project. I only need to create one simple class which has the basic database information to plug my business logic with the Microsoft DataApplicationBlocks. From my own data access class, I only need to provide a transaction call for my data base activates. In .NET 2.0, a transaction scope is also introduced to handle the multiple transactions. So I only need to create one transaction scope in my own data access class to monitor all my data access work. In order to make the application to be more configurable, I decide to put the database connection sting in a configuration file, which is an xml based format. User can easily modify the connection string to point to the different database. As I know that database object is unmanaged component and the garbage collector wound not clean them up. In order to prevent the memory leak issue, so I have to properly dispose my data access object manually.The approach I can use is to implement IDisposeable interface to my data access object to dispose all the connection whenever my data access object need to be destroyed. In the data access layer, the identity map of Object-Relational behavioral design pattern (Fowler, M. 2007) can be applied to only allow the each object entity to be loaded once. Therefore, the ID attribute is really helpful in the business entity class to track each unique record. It should help to improve the performance because the objet entity is loaded once and cached to be reused again and again.
Design of workload system
For the user’s convenience, I decide to create a WorkLoad system to be a window application that can be easily installed on the user’s pc. There is couple use cases persist in the workload system (see Figure -5).
User click new SLP button to invoke a SLP sub form. User starts typing all the SLP’s information on a SLP sub form. Click save button to save the SLP to the database. (see Figure -6)
User views all the patients from the window form datagrid. User selects one patient to start editing his information. (See Figure -7)
Create WorkLoad and extends Validate Business Rules
User creates a new workload and assigns a SLP to it.In the workload form , user can select number of the patient to the assigned SLP. Once the workload is created, it will be passed to the rules engine object to start validating. The rule engine returns the result to workload form that displays it to user for review. (see Figure -8)
Business class diagram (Figure -9) shows all the business class. I focus on the database entities only at this time.Log and exception class can be borrowed from the Microsoft application block as well.
Figure - 9
Rule Engine class (Figure – 10) diagram shows all the Rule engine component classes.
Figure - 10
Database Entity relationship diagram (Figure -11) illustrates the all the relational data table I need for the workload system.
Quality Attribute Scenarios
In order to meet the goals of the quality attributes that can supported the workload system architecture. The Quality attribute matrix describes the tactics and the approaches that related to all the quality attributes.
The workload system is windows .NET application. The application will be directly installed on the client’s machine, therefore it perform as single application. There is no limitation for the availability. No internet access needed. The database will also be installed on the same machine.
The application can also be deployed by using the ClickOnce technology. The client will received a notification about the new updates whenever the new version of the workload system is published on the server.
Windows ClickOnce updating services.
Authentication can be used to allow the valid user to user the application. And authorization can be configured from the configuration to limit the user access the local database. Audit table trace all the activities.
Authorize Users, Limit Access, and Audit Trail.
Since it is a windows application, the single user is the most case be applied for the system.
Singleton pattern is applied for rules engine
The window from will be the only interface which most user are already similar with. Simply button click provides most functionality. Sub form will be invoked for each activity.
Separate User Interface, Cancel, Save function exists for most of the forms
.Net framework and SQL express database are both free can be downloaded from Microsoft. Web site. Client pays nothing.
Cost Analysis and development only
Based on the above analysis and design, I have described very detailed information about the workload system. There are also some advantages of using design patterns to support the workload system architecture. Since I also gain knowledge about the .NET 2.0 Framework, I feel very comfortable using .NET technology and SQL Server 2005 to achieve the implementation.
The rules used in this system have been reviewed by Speech Language Pathologists (my wife) who is going to work in the school system and also by her supervisor. The Speech Language Pathologist stated that the rules are valid and the system will be very helpful for school based SLPs to calculate their workload. The system will be implemented as a tool that will be distributed for school based SLPs to review and to test in the future.