Analyze, model, and refactor JavaScript codebases with auto-generated Class-Responsibility-Collaborator models.
MIT License
eslint-plugin-crc
Analyze, model, and refactor JavaScript codebases with auto-generated Class-Responsibility-Collaborator models.
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:
</blockquote>
</th>
class Polygon {
constructor(height, width) {
this.height = height;
this.width = width;
this.name = "Polygon";
}
}
module.exports = Polygon;
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.
/**
* 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;
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.
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
}
}
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
CRC Models use a simple and scannable template that consist of three simple sections for:
Despite the implementation of the
class
,constructor
,static
,extends
, andsuper
keywords in ES2015, JavaScript still achieves encapsulation, inheritance, and polymorphism withprototype
chains. Nevertheless, I use the wordclass
to refer to JavaScript objects withprototype
-based inheritance.
CRC Models express how classes (i.e., prototyped JavaScript objects) behave and interact in order to fulfill their specified responsibilities.
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.
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.
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.
eslint-plugin-crc
's latest version is v0.2.0
. Please read the CHANGELOG for details.
[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]