Skip to content

gregswindle/eslint-plugin-crc

Repository files navigation

eslint-plugin-crc

Analyze, model, and refactor JavaScript codebases with auto-generated Class-Responsibility-Collaborator models.

License FOSSA Status NSP Status Dependencies Dependencies
Travis branch AppVeyor Windows build status Coveralls coverage Codacy Badge Quality Gate PRs Welcome

Table of contents

1. Refactoring with CRC models

Citation Refactoring is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior.

Its heart is a series of small behavior preserving transformations. Each transformation (called a “refactoring”) does little, but a sequence of transformations can produce a significant restructuring. Since each refactoring is small, it’s less likely to go wrong. The system is kept fully working after each small refactoring, reducing the chances that a system can get seriously broken during the restructuring.[1]

CRC Models can help you pinpoint where problems might be, and reveal potential improvements to your design.


Example: two prototypes (classes) called Polygon and Square:

class Polygon extends Object

  </blockquote>
  </th>
Responsibilities Collaborators
Select to toggle Details...
Source code
class Polygon {
  constructor(height, width) {
    this.height = height;
    this.width = width;
    this.name = "Polygon";
  }
}

module.exports = Polygon;
References
Polygon is referenced n times in n1 files.

  1. TODO: reference one.
  2. TODO: reference two.
  3. TODO: reference one.
    Undetermined.
    None found.

class Square extends Polygon

A plane figure with four equal straight sides and four right angles.
Responsibilities Collaborators
Select to toggle Details...
Example
let shape = new Square(5);
console.log(`${shape.name} has
  a height ${shape.height} and
  a width of ${shape.width},
  for an area of ${shape.area}.`);
// =>
// Square has
//  a height 5 and
//  a width of 5,
//  for an area of 25.
Source code
/**
 * A plane figure with four equal straight sides and four right
 * angles.
 *
 * @property {number} area - The extent of a two-dimensional figure
 * or shape, or planar lamina, in the plane.
 * @property {string=Square} name - The geometric `object`'s name.
 * @example
 * let shape = new Square(5)
 * console.log(`${shape.name} has
 *   a height ${shape.height} and
 *   a width of ${shape.width},
 *   for an area of ${shape.area}.`)
 * @extends Polygon
 */
class Square extends Polygon {
  /**
   * Call the parent class's constructor with lengths
   * provided for the Polygon's width and height.
   * @param {!number=0} length - The length of all sides.
   * @constructor
   */
  constructor(length = 0) {
    super(length, length);
    this.name = "Square";
  }

  get area() {
    return this.height * this.width;
  }

  set area(value) {
    this.height = this.width = Math.sqrt(value);
  }
}

module.exports = Square;
References
Square is referenced n times in n1 files.

  1. TODO: reference one.
  2. TODO: reference two.
  3. TODO: reference one.
  1. Get the extent of a two-dimensional figure or shape, or planar lamina, in the plane.
  2. Set the extent of a two-dimensional figure or shape, or planar lamina, in the plane.
  1. Math [10:20]

2. Installation

You'll first need to install ESLint:

$ npm i eslint --save-dev

Next, install eslint-plugin-crc:

$ npm install eslint-plugin-crc --save-dev

Note: If you installed ESLint globally (using the -g flag) then you must also install eslint-plugin-crc globally.

3. Configuration

Add crc to the plugins section of your .eslintrc configuration file. You can omit the eslint-plugin- prefix:

{
  "plugins": ["crc"]
}

Then configure the rules you want to use under the rules section.

{
  "rules": {
    "crc/generate-crc": 2
  }
}

4. Usage

For local installations, run:

$ ./node_modules/.bin/eslint \
  -f './lib/formatters/crc/index.js' tests/fixtures/crc/class-declaration/*.js \
  -o reports/crc-model-report.md

If you installed eslint-plugin-crc globally, run:

$ eslint \
  -f './lib/formatters/crc/index.js' tests/fixtures/crc/class-declaration/*.js \
  -o reports/crc-model-report.md

5. Anatomy of a CRC model

CRC Models use a simple and scannable template that consist of three simple sections for:

  1. Name: what the class (or object) is called in source code.
  2. Responsibilities: the work that the class/object is supposed to perform, and the data it's supposed to maintain.
  3. Collaborators: other objects this class directly invokes in order to do its work.
Class/Object name
Responsibilities Collaborators

The class/object's activities and purpose:

  1. What the class/object does.
  2. The information it maintains.

Objects that this class depends on to:

  1. Assist Class name with its work.
  2. Provide info/data that Class name needs.

Use of terms Despite the implementation of the class, constructor, static, extends, and super keywords in ES2015, JavaScript still achieves encapsulation, inheritance, and polymorphism with prototype chains. Nevertheless, I use the word class to refer to JavaScript objects with prototype-based inheritance.

6. Benefits

6.1. Simplicity

CRC Models express how classes (i.e., prototyped JavaScript objects) behave and interact in order to fulfill their specified responsibilities.

Citation A Class Responsibility Collaborator (CRC) model...is...divided into three sections.... A class represents a collection of similar objects, a responsibility is something that a class knows or does, and a collaborator is another class that a class interacts with to fulfill its responsibilities.[2]

CRC models are simple to read, write, and update. CRC models focus on the purpose of classes instead of their mechanics. Because of their simplicity, CRC models are useful for determining why software might be difficult to extend or change.

6.2. Behavior-driven development

Behavior-driven development (BDD) seeks to incorporate design as a routine exercise during product delivery. BDD prescribes iterative activities intended to redefine and contextualize design, testing, and programming as unified activities that share common specifications expressing a product's behavior instead of its technical implementation. BDD extends TDD's focus on refactoring to how classes behave with each other. The very structure of Class-Responsibility-Collaboration models, with their emphasis on the appropriate distribution of responsibilities among classes (and therefore how those classes collaborate) reflects BDD's emphasis on behavior instead of technical assertions.

7. Contributing

PRs Welcome We welcome contributors and pull requests.

Check out the guidelines for

Contributions are stories with a beginning, a middle, and an end, all told through issues, comments, commit logs, and pull requests.

8. Version

eslint-plugin-crc's latest version is v0.2.0 . Please read the CHANGELOG for details.

9. License

MIT © Greg Swindle

FOSSA Status

10. References

[1] M. Fowler, "Refactoring", Refactoring.com, 2017. [Online]. Available: https://refactoring.com/. [Accessed: 22- Nov- 2017]

[2] S. Ambler, "Class Responsibility Collaborator (CRC) Models: An Agile Introduction", Agilemodeling.com, 2017. [Online]. Available: http://agilemodeling.com/artifacts/crcModel.htm. [Accessed: 22- Nov- 2017]


License Readme Score Greenkeeper