Post #15

We have begun work on the web application for the final assignment, so I wanted to find out what design patterns and principles are most commonly used in the development of web applications.  The result the came up the most, in my search, was the Inversion of Control (IoC) principle, a design principle used to increase the modularity and extensibility of  programs, especially web applications that expect to experience growth.  This principle is also useful in event-driven programs, which is how it relates to a project like ours  While we don’t really need to consider the growth of our application in the context of our class, it could be potentially useful to follow the Inversion of Control principle as much of our application will be event-driven.  I found it incredibly interesting to learn about the IoC principle and knowing how it works will surely benefit me in the development of other web applications in the future.

IoC is a design principle in which most of a program’s flow of control is received from a framework, rather than being directly implemented in the main parts of the program.  In traditional programming, the code that expresses the purpose of the program calls into libaries to perform tasks, but with IoC, it is the framework that calls the task-specific code.  This principle is given its name because adhering to it effectively inverts the control of the program from implementation to frameworks.  Adhering to the IoC principle serves the purposes of decoupling execution of tasks from implementation, focusing a module on task it is designed for, freeing modules from assumptions, and preventing side effects when replacing a module.  Software frameworks, schedulers, event loops, dependency injections, template methods, and callbacks all follow the IoC principle.

The IoC design pattern is, in my opinion, a difficult one to fully grasp.  The most helpful explanation I found about the pattern was in a YouTube video uploaded by Christian Richards, entitled “Programming – What is… Inversion of Control”.  In the video, Christian provides the example of a program that wishes to make a new user; when constructed, an integer variable is passed in, as a parameter, to the User class’s constructor and is used to dictate what kind of SQL Database Access Layer (DAL) will be initialized and stored in the new user.

The fact that the User class is responsible for a new DAL object to store within itself means that the User class is tightly coupled with the creation of new DAL objects. 

In order to improve the modularity and extensibility of the program, Christian knows that he should adhere to the IoC principle, and decouple the creation of DAL objects from the User class.  The User class should not contain code for deciding which kind of DAL should it should use; instead it should simply know how to work with DALs, and let the implementation dictate which DAL to use.  This can be done by creating an interface to represent DAL objects (let’s call it ‘IDAL’), create concrete DAL objects for each different kind of DAL and implement IDAL in each one, modify the User class’s constructor to take objects of IDAL type, and then modify the main implementation of the program to create and pass in a concrete DAL object to the User constructor, upon construction.  Now, the User class is simply responsible for dealing with the DAL object, rather than deciding which kind of DAL object to use and only then working with it.

Here are excerpts of Christian’s program, before and after adherence to the IoC principle:
class Program
{
static void Main(string[] args)
{
User user = new User(1);
}
}
class User
{
IDAL dal;
public User(int IDALtype)
{
if(IDALtype == 1)
{
dal = new MySQLDAL();
}
else
{
dal = new SqlServerDAL();
}
}


class Program
{
static void Main(string[] args)
{
User user = new User(new MySQLDAL());
}
}
class User
{
IDAL dal;
public User(IDAL IDALtype)
{
dal = IDALtype;
}
}
Continue reading “Post #15”

Advertisements

Post # 13

While researching Angular for the final project, I came across a really useful blog post written by Todd Motto, owner of Ultimate Angular, entitled “Ultimate guide to learning Angular in one day“.  I was intrigued by this post because it contains a section solely devoted to defining the terminology that is commonly-used in Angular development, which I found to be incredibly helpful.  In this blog post, I will reiterate the definitions of the most important terms, in hopes that it will aid me in the development of my team’s application.

The article begins by defining what exactly Angular is and what it is used for.   Motto defines Angular as a “client-side MVC/MVVM framework built in JavaScript, essential for modern single page web applications (and even websites)”.  MVC is short for Model-View-Controller, and MVCs are used in many programming languages as a means of structuring software.  Model refers to the data structure behind a specific portion of an application, usually ported in JSON; View refers to the HTML and/or rendered output of an application.  By using an MVC, you’ll pull down Model data which updates your View and displays the relevant data in the HTML; Controller refers to a mechanism, within an application, that provides direct access from the server to the view so that data can be updated on the fly via communication between the server and client(s).

Motto then explains how to set up an Angular project with the bare essentials.  The essential elements that make up an Angular application are a definition, controllers, and binding and inclusion of Angular within an HTML file.

Controllers, as defined by Motto, are the direct access points between the server and view that are used to update data on-the-fly .  The HTML of an Angular application should contain little to no physical text or hard coded values – this is because all of that data should be pushed into the view from a controller.  Web-applications should be as dynamic as possible and, by pushing values to the view from a controller in the back-end, we can achieve this.  Motto then emphasizes that Controllers are to be used for data only, and creating functions that are used in communication between the server and JSON.

Directives, as defined by Motto, are small pieces of templated HTML that should be used multiple times throughout an application’s development.  Directives are the easiest way to push data into the view.  Directives consist of a list of properties, including: restrict (restriction of element’s usage), replace (replaces markup in view that defines directive), transclude, template (allows declaration of markup to be injected into the view), templateURL (similar to template but kept in its own file).

Services, as defined by Motto, are stylistic design patterns.  Services are used for singletons, and Factories are used for functions.  Filters are used in conjunction with arrays to loop through data and filter specific findings.

Two-way data-binding, is a full-circle of synhronized data; update the Model and it updates the View, update the View and it updates the Model.  This implies that data is kept in sync without issue.

A lot of the results of my research into Angular, at first, were of no use because I had little understanding of the terminology and concepts described in them.  I believe that this post gave me a good understanding of the fundamental concepts of Angular and I now feel more confident as I continue development of my own application.  I will likely refer back to this article as I make progress in my project and, inevitably, conduct more research.

Post #11

This week, I thought it would be useful to look into how testing is conducted in TypeScript, to follow up to Post #8.  I found a blog post by Sudarsan Balaji, entitled “Unit testing node applications with TypeScript — using mocha and chai“, that describes the process of using the assertion library chai in conjunction with the testing framework mocha to conduct unit testing on node applications written in TypeScript.  I believe that knowing how to conduct proper unit testing in TypeScript will give me an advantage in the upcoming assignment as well as the final project of the semester.

Balaji begins the article by explaining his reason for advocating the use of mocha and chai, specifically, and also how to install them.  As I explained in the introduction to this post, mocha is a noteable JavaScript testing framework and chai is an assertion library (a collection of tools to assert that things are true/correct).  Balaji believes these these two tools work well together because they are simple yet effective enough to get the job done.  I’m not going to explain the installation, here, but once you have mocha and chai installed, you simply create a new TypeScript file and invoke some import statements.  Balaji then provides an example of a TypeScript test (I added some comments for clarity):

/** hello-world.spec.ts */
import { hello } from ‘./hello-world’;
import { expect } from ‘chai’;
import ‘mocha’;

describe(‘Hello function’, ( ) => { /** test group name */
it(‘should return hello world’, ( ) => { /** specific test */
const result = hello( ); /** run hello( ) function from hello-world program
expect(result).to.equal(‘Hello world!’); /** compare result to expectation */
});
/** to test something else we would just add more it( )statements here */
});

Sample expected output:
Hello function
√ should return hello world

1 passing (8ms)

To run this unit test, Belaji recommends creating an npm script that calls mocha and passes in the path as a parameter.  This can be done, for this example, by creating a JSON file with the following contents:

/** package.json */
{
“scripts”: {
“test”: “mocha -r ts-node/register src/**/*.spec.ts”,
},
}

(For those unaware, a JSON file is a JavaScript Object Notation file.  JSON files are written in JavaScript object notation and are used for storing in exchanging data.  In this example, we are using it to store a script that we will run from the console, using npm.  i.e. npm run test)

The remainder of Belaji’s post is a discussion of using mocha and chai to conduct unit testing on client-side applications.  The final project may require me to delve into this aspect of TypeScript testing, but because I have yet to begin work on the final project, I think I will refer back to this section of his post and summarize it later, if I feel the need to.   Given the nature of the projects we are working on, right now, I think it is sufficient to stop this post here.  I now have an introductory understanding of how to conduct unit testing in TypeScript, which I can now use to assure that I am producing quality JavaScript applications.

Post #10

This week, I will be preparing a tutorial on the Observer Design Pattern and I figured I could assist my own understanding of the pattern by writing a blog post to accompany it.  This post will be a summary of the Observer pattern as it is described on this page of the Object Oriented Design website.  The motivation behind the Observer pattern is the frequent need of objects, in object oriented programming, to be informed about the changes that occur in another object.  An exemplification of this concept in the real-world can be imagined as a stock system which provides data for several types of client; the subject(stocks server) needs to be separated from its observers(client applications) in such a way that adding a new observer would be transparent to the servers.

The intention of implementing the Observer pattern is to define a one-to-many dependant relationship between objects so that when an object’s state is altered, its dependants are notified and updated automatically.  The Observer pattern is effectively adhered to with the implementation of 4 classes:

  • Observable/Subject(GOF) – interface or abstract class; defines operations for attaching/de-attaching observers to client
  • ConcreteObservable – concrete Observable class; maintains state of an object and notifies Observers when a change occurs
  • Observer – interface or abstract class; defines notification operations
  • ConcreteObserverA, ConcreteObserver2, etc. – concrete Observer implementations

How it Works:

  • ConcreteObserverable object is instantiated in main framework
  • ConcreteObserver objects are instantiated and attached to ConcreteObservable object via methods defined in the Observable interface
  • ConcreteObserver objects are notified each time the state of the ConcreteObservable object is changed
  • ConcreteObservers are added to the application by simply instantiating them in the main framework and attaching them to the ConcreteObservable object

This allows for classes, that are already created, to remain unchanged.

The Observer pattern is applicable in situations where the change of a state in one object must be reflected in another object without keeping the objects coupled, and in situations where the main framework needs to introduce new observers with minimal changes.

The Observer pattern is often used, in conjunction, with other design patterns:

  • Factory – A Factory pattern can be utilized to create observers so no changes will be required in main framework
  • Template – An Observer pattern can be utilized to make sure that Subject state is self-consistent
  • Mediator – A Mediator pattern can be utilized in cases of many subjects and many observers

The Observer pattern is so well-known because its implementation has proven to be quite powerful in event handling systems of languages such as Java and C# and in the model-view-controller architectural pattern.  I am excited to put together a tutorial on how to use this pattern and I believe that having a good grasp on its motivations and intentions will aid me in future if I ever consider using it.

Post #8

We have recently begun preparing for the final project of the semester, in which we will design and develop a web application using TypeScript, a superset of JavaScript that is developed by Microsoft.  I wanted to find out more information about TypeScript and how it compares to normal JavaScript, so I began researching the matter and decided to kill two birds with one stone and write a blog post about my findings.  I found the aptly-named article “TypeScript vs. JavaScript”, written by Ayo Alfonso, which details their contrasting elements.

Alfonso begins the article by defining TypeScript as the superset of JavaScript that brings users optional static types and solid tooling.  Using TypeScript can help avoid painful bugs people commonly run into when writing JavaScript by type-checking your code.  It can also report issues without you even saving your file, and leverage the type system to help you write code even faster.

JavaScript, as many of you probably know, is one of the core programming languages for producing web-based content.  JavaScript is dynamically typed, and Alfonso believes that its untyped nature and unique prototypal inheritance structure is not only what drew everybody in to using it but is also the cause of its shortcomings when utilized in large applications.  TypeScript is the solution to these shortcomings because of its statically typed nature – the types of variables and class method parameters are defined, in the written code, to help the IDE and compiler spot errors,  but at compilation time the TypeScript is translated into regular JavaScript.  Alfonso goes on to explain the difference between static and dynamic typing.

To summarize:

Statically typed languages verify and enforce the constraints of types, declared in code, at compile-time. TypeScript is a statically typed language.

Dynamically typed languages verify and enforce the constraints of types at run-time; types are not associated with variables and parameters in the written code but are instead inferred at run-time and then type-checked.  Dynamically typed languages look at the value of a variable, at run-time, and infer its type. JavaScript is a dynamically typed language.

Alfonso claims that, while static languages make the programmer more accountable for their code, it is beneficial to use a statically typed language because they are generally faster, more efficient, and more effective.  Programmer accountability, in statically typed languages, can be seen as a benefit as well because it encourages good programming practices.  I believe that programmer accountability does lead to the production of better code and I am excited to work with TypeScript in the upcoming project.  I now understand why we are using TypeScript instead of JavaScript and I think having this background knowledge will help me in writing code in both languages.

Post #6

Toward the end of our discussion about the Strategy design pattern, we briefly talked about the open/closed principle; I wanted to further my understanding of this concept, so I decided to do some research of my own.  Today, I will summarize an article by Swedish systems architect Joel Abrahamsson entitled “A simple example of the Open/Closed Principle”.

Abrahamsson begins the article by summarizing the open/closed principle as the object oriented design principle that software entities should be open for extension, but closed for modification.  This means that programmers should write code that doesn’t need to be modified when the program specifications change.  He then explains that, when programming in Java, this principle is most often adhered to when implementing polymorphism and inheritance.  We followed this principle in our first assignment of the class, when we refactored the original DuckSimulator program to utilize the Strategy design pattern.  We realized, in our in-class discussion of the DuckSimulator, that adding behaviors to Ducks would force us to update the implementation of the main class as well as each Duck subclass.  By refactoring the code to implement an interface in independent behavior classes – and then applying those behaviors to Ducks in the form of “setters” – we opened the program for extension and left it closed for modification.  Abrahamsson then gives his own example of how the open/closed principle can improve a program that calculates the area of shapes.  The idea is that, if the open/closed principle is not adhered to in the implementation of a program like this, it is susceptible to rapid growth as functionality is added to calculate the area of more and more shapes.

(Note: This is clearly not a Java implementation.)

public double Area(object[] shapes)
{
    double area = 0;
    foreach (var shape in shapes)
    {
        if (shape is Rectangle)
        {
            Rectangle rectangle = (Rectangle) shape;
            area += rectangle.Width*rectangle.Height;
        }
        else
        {
            Circle circle = (Circle)shape;
            area += circle.Radius * circle.Radius * Math.PI;
        }
    }

    return area;
}

( Abrahamsson’s implementation of an area calculator that does not adhere to the open/closed principle. )


public abstract class Shape
{
    public abstract double Area();
}
public class Rectangle : Shape
{
    public double Width { get; set; }
    public double Height { get; set; }
    public override double Area()
    {
        return Width*Height;
    }
}
public class Circle : Shape
{
    public double Radius { get; set; }
    public override double Area()
    {
        return Radius*Radius*Math.PI;
    }
}
public double Area(Shape[] shapes)
{
    double area = 0;
    foreach (var shape in shapes)
    {
        area += shape.Area();
    }

    return area;
}

( Abrahamsson’s implementation of an area calculator that adheres to the open/closed principle. )

Abrahamsson ends the article by sharing his thoughts on when the open/closed principle should be adhered to.  He believes that the primary focus of any good programmer should be to write code well enough that it doesn’t need to be repeatedly modified as the program grows.  Conversely, he says that the context of each situation should be considered because unnecessarily applying the open/closed principle can sometimes lead to an overly complex design.  I have always known that it is probably good practice to write code that is prepared for the requirements of the program to change, and this principle confirmed that idea.  From this point forward, I will take the open/closed principle into consideration when tackling new projects.