Bitwise Operators Part 5

At Part 4, we’ve written the persistence layer, now, let’s write the Repository, but, first, let’s remember the foundations of the Repository Pattern:

Repositories are classes or components that encapsulate the logic required to access data sources. They centralize common data access functionality, providing better maintainability and decoupling the infrastructure or technology used to access databases from the domain model layer.

https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/microservice-ddd-cqrs-patterns/infrastructure-persistence-layer-design

So, at our POC, the file is into the ./repositories folder, and must have the logic to access the data, but decoupled from the data access layer. Our starting point is:

import { LocalStoreManager } from '../dataAccess/localStoreManager.js';

const lsm = new LocalStoreManager();

export class LocalStateRepository {
  createState(stateName, stateId) {}

  getStates() {}

  createBitwiseOrRule(ruleName, stateArray) {}

  getRules() {}

  clearAllData() {}
}

We have an instance of the LocalStoreManager class and:

createState method: the name is clear! It creates a state with a given state name and a state Id.

getStates method: this method retrieves all created states.

createBitwiseOrRule method: it creates a rule combining one or more states using the Bitwise Or Operator.

getRules method: this method retrieves all created rules.

clearAllData method: it deletes all states and rules from the database (in this POC, from the LocalStore).

Note that all method names are really meaningful. For ex., createSt is way different from createState! You can write a comment explaining what the method does, but, think, with a few letters, the method becomes self-explanatory!

Let’s code!

Creating a State

The code organisation starts to be evident! Our generic ‘saveObject’ method receives two arguments: a key and a value, so, as a key, we’ll use the state name, and for the value, we will stringify a JSON with two properties, a type (we’ll need to differentiate a state from a rule) and a value.

createState(stateName, stateId) {
    lsm.saveObject(
      stateName,
      JSON.stringify({ type: 'state', value: stateId })
    );
  }

Retrieving all created states

Here we’ll create a private and generic method which will retrieve an array using the type passed as an argument.

We’ll also use a functional programming paradigm in our POC heavily OOP, the immutability.

In a nutshell, is a paradigm which says, once created, an object cannot be changed. Why I did this? Because as we can read at the http://dev.to website:

Functional programming techniques and design patterns are increasingly popular in JavaScript applications.  Tools and frameworks such as RxJSRedux, and React take inspiration from functional reactive programming, for example.

https://dev.to/glebec/four-ways-to-immutability-in-javascript-3b3l

I agree with the author when he writes: ” JavaScript is a multi-paradigm programming language “!

Click on the link above and read all the post, it’s quite informative!

First step is retrieve the state object: let’s remember how is the localStorageObject

{
   TEST1: "{"type":"state","value":1}",
   TEST2: "{"type":"state","value":2}",
   TEST3: "{"type":"state","value":4}", 
   TEST4: "{"type":"state","value":8}" 
 }

Our method receives the information and transform in an State Array. The algorithm is:

function getItemsByType(type) {
  const localStorageObject = lsm.getObject();
  let statesArray = [];
  for (const key in localStorageObject) {
    if (localStorageObject.hasOwnProperty(key)) {
      const element = JSON.parse(localStorageObject[key]);
      if (element.type === type.toLowerCase()) {
        const temp = {};
        temp.state = key;
        temp.value = element.value;
        statesArray.push(temp);
      }
    }
  }

  return statesArray;
}

As a generic method, we can reuse it to retrieve all states and all rules!

Our public method will be:

getStates() {
  return getItemsByType('state');
}

And, till now, our class should look like this:

import { LocalStoreManager } from '../dataAccess/localStoreManager.js';

const lsm = new LocalStoreManager();

function getItemsByType(type) {
  const localStorageObject = lsm.getObject();
  let statesArray = [];
  for (const key in localStorageObject) {
    if (localStorageObject.hasOwnProperty(key)) {
      const element = JSON.parse(localStorageObject[key]);
      if (element.type === type.toLowerCase()) {
        const temp = {};
        temp.state = key;
        temp.value = element.value;
        statesArray.push(temp);
      }
    }
  }

  return statesArray;
}

export class LocalStateRepository {
  createState(stateName, stateId) {
    lsm.saveObject(
      stateName,
      JSON.stringify({ type: 'state', value: stateId })
    );
  }

  getStates() {
    return getItemsByType('state');
  }

  createBitwiseOrRule(ruleName, stateArray) {}

  getRules() {}

  clearAllData() {}
}

Please note the private method isn’t into the LocalStateRepository class. It is accessible by the public method because of the Javascript Closure (please see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures#Emulating_private_methods_with_closures – this example is using a constructor function, mine, an ES6 class, but, the concept is the same), but, it isn’t directly accessible from a class instance.

Creating a Bitwise OR rule

The method expects two parameters: a name and an array with the states which will compose a rule.

This is the algorithm:

  • Create a variable named `value` which value is undefined;
  • Retrieve the localStoreObject;
  • Iterate through the received array using foreach, and parse the value
createBitwiseOrRule(ruleName, stateArray) {
    let value = undefined;

    const lsObject = lsm.getObject();
    stateArray.forEach(memberName => {
      const obj = JSON.parse(lsObject[memberName]);
      if (obj.type === 'state') {
        value = value | obj.value;
      }
    });

    lsm.saveObject(ruleName, JSON.stringify({ type: 'rule', value }));
  }

Here a quick reminder: you can use dot notation or square bracket notation to access the value of a JSON property, right? Here is an example when using square bracket notation to access the property value!

To understand how the value = value | obj.value; works, go to the Part 2 and read more about the Bitwise OR Operator!

Retrieving all created rules

After all the explanation above, you already know how the code will be:

getRules() {
  return getItemsByType('rule');
}

Deleting all data

To delete all data is easy!

  clearAllData() {
    lsm.clearData();
  }

The complete code

Your complete code should look like this:

import { LocalStoreManager } from '../dataAccess/localStoreManager.js';

const lsm = new LocalStoreManager();

function getItemsByType(type) {
  const localStorageObject = lsm.getObject();
  let statesArray = [];
  for (const key in localStorageObject) {
    if (localStorageObject.hasOwnProperty(key)) {
      const element = JSON.parse(localStorageObject[key]);
      if (element.type === type.toLowerCase()) {
        const temp = {};
        temp.state = key;
        temp.value = element.value;
        statesArray.push(temp);
      }
    }
  }

  return statesArray;
}

export class LocalStateRepository {
  createState(stateName, stateId) {
    lsm.saveObject(
      stateName,
      JSON.stringify({ type: 'state', value: stateId })
    );
  }

  getStates() {
    return getItemsByType('state');
  }

  createBitwiseOrRule(ruleName, stateArray) {
    let value = undefined;

    const lsObject = lsm.getObject();
    stateArray.forEach(memberName => {
      const obj = JSON.parse(lsObject[memberName]);
      if (obj.type === 'state') {
        value = value | obj.value;
      }
    });

    lsm.saveObject(ruleName, JSON.stringify({ type: 'rule', value }));
  }

  getRules() {
    return getItemsByType('rule');
  }

  clearAllData() {
    lsm.clearData();
  }
}

With this class, we finished our infrastructure persistence layer using a simplified version of the repository pattern.

See you next week with the logic and some manual tests.

Happy coding!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s