Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
out
.vscode
.DS_Store
*~
node_modules/
dist/
36 changes: 35 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,35 @@
# DesignPatternsExamples-Fall2020
# DesignPatternsExamples-Fall2020

This fork reorganizes the multiple examples for better use with VSCode, and
two new variants on filesystem-visitor.

1. The various examples are now kept in the folder all-examples/ . To run
one or more of the examples, move its folder to live directly under src/ .
I've updated the npm scripts so that "npm run run" will compile all .ts files
contained in the directory tree under src, and will run all the
dist/*/index.js files it finds. [Thanks to Satya who showed me how to do
this.]

2. I've added a variant entitled filesystem-visitor-no-autorecursion. I did
not like the fact that recursion through directories was automatic. It's as
if every "ls" was an "ls -R". The -no-autorecursion removes the recursive
calls to the visitor from directory.ts ; instead it adds a getChildren method
to the Directory class, and the DuVisitor explicitly recurs on the children.

3. I've added a variant entitled filesystem-visitor-better-names. This is
identical to filesystem-visitor-no-autorecursion except that

(a) "accept" in Node is now called "acceptVisitor", and
(b) visitFile, etc, are now called "ifFile". I think these names make the
connection between the visitor pattern and a case structure clearer.

also
(c) duVisitor now takes one constructor argument, called startingNode, and its
constructor initiates the visit by calling
startingNode.acceptVisitor(this).

also
(d) I've cleaned up the code inside duVisitor to move all those private
variables out of the constructor where I don't think they belonged.

Enjoy!
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
29 changes: 29 additions & 0 deletions all-examples/filesystem-visitor-better-names/directory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Node from './node'
import IFileSystemVisitor from './ifilesystemvisitor';

class Directory extends Node {

private children: Array<Node>;

constructor(n: string, p?: Directory){
super(n,p);
this.children = [];
}
public getAbsoluteName() : string {
return super.getAbsoluteName() + "/";
}

public getChildren(): Array<Node> { return this.children }

public add(n: Node) : void {
this.children.push(n);
}
public acceptVisitor(v: IFileSystemVisitor) : void {
v.ifDirectory(this);
// no, it's up to the visitor to decide whether to recur on the children
// this.children.forEach((child) => child.accept(v))
}

}

export default Directory
36 changes: 36 additions & 0 deletions all-examples/filesystem-visitor-better-names/duvisitor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Node from './node'
import File from './file'
import Directory from './directory'
import Link from './link'
import IFileSystemVisitor from './ifilesystemvisitor';

class DuVisitor implements IFileSystemVisitor {
private nrFiles = 0
private nrDirectories = 0
private nrLinks = 0
private totalSize = 0
constructor(startingNode: Node) {
startingNode.acceptVisitor(this);
}

public ifFile(f: File): void {
this.nrFiles++;
this.totalSize += f.size();
}
public ifDirectory(d: Directory): void {
this.nrDirectories++;
d.getChildren().forEach((child) => child.acceptVisitor(this))
}
public ifLink(l: Link): void {
this.nrLinks++;
}

public report(): void {
console.log("files: " + this.nrFiles);
console.log("directories: " + this.nrDirectories);
console.log("links: " + this.nrLinks);
console.log("total size: " + this.totalSize);
}
}

export default DuVisitor
20 changes: 20 additions & 0 deletions all-examples/filesystem-visitor-better-names/file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Directory from './directory'
import Node from './node'
import IFileSystemVisitor from './ifilesystemvisitor';

class File extends Node {
private content: string

constructor(n: string, p: Directory, content: string){
super(n,p);
this.content = content;
}
public acceptVisitor(v: IFileSystemVisitor) : void {
v.ifFile(this);
}
public size() : number {
return this.content.length;
}
}

export default File
11 changes: 11 additions & 0 deletions all-examples/filesystem-visitor-better-names/ifilesystemvisitor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Directory from './directory';
import Link from './link';
import File from './file'

interface IFileSystemVisitor {
ifFile(f: File) : void;
ifDirectory(d: Directory): void;
ifLink(l: Link): void;
}

export default IFileSystemVisitor
20 changes: 20 additions & 0 deletions all-examples/filesystem-visitor-better-names/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Directory from './directory'
import File from './file'
import Link from './link';
import DuVisitor from './duvisitor';

let root = new Directory("");
new File("core", root, "hello");
let usr = new Directory("usr", root);
new File("adm", usr, "there");
new Directory("foo", usr);
new File("bar1", usr, "abcdef");
new File("xbar2", usr, "abcdef");
new File("yybarzz3", usr, "abcdef");
let link = new Link("link", usr, root);
new Link("link2", link, root);

let visitor = new DuVisitor(root);
// root.acceptVisitor(visitor);
visitor.report();

20 changes: 20 additions & 0 deletions all-examples/filesystem-visitor-better-names/link.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Directory from "./directory";
import Node from "./node"
import IFileSystemVisitor from "./ifilesystemvisitor";

class Link extends Node {
private realNode: Node;

constructor(n: string, w: Node, p: Directory){
super(n,p);
this.realNode = w;
}
public getAbsoluteName() : string{
return super.getAbsoluteName() + "@";
}
public acceptVisitor(v: IFileSystemVisitor) : void {
v.ifLink(this);
}
}

export default Link
22 changes: 22 additions & 0 deletions all-examples/filesystem-visitor-better-names/node.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Directory from './directory'
import IFileSystemVisitor from './ifilesystemvisitor';

abstract class Node {
protected name: string;
protected parent: Directory;

constructor(name: string, parent: Directory) {
this.name = name; this.parent = parent;
if (this.parent != null) { this.parent.add(this); }
}
public getAbsoluteName() : string {
if (this.parent != null) {
return this.parent.getAbsoluteName() + this.name;
}
return this.name;
}
public toString() : string { return this.getAbsoluteName(); }
public abstract acceptVisitor(v: IFileSystemVisitor) : void;
}

export default Node
29 changes: 29 additions & 0 deletions all-examples/filesystem-visitor-no-auto-recursion/directory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Node from './node'
import IFileSystemVisitor from './ifilesystemvisitor';

class Directory extends Node {

private children: Array<Node>;

constructor(n: string, p?: Directory){
super(n,p);
this.children = [];
}
public getAbsoluteName() : string {
return super.getAbsoluteName() + "/";
}

public getChildren(): Array<Node> { return this.children }

public add(n: Node) : void {
this.children.push(n);
}
public accept(v: IFileSystemVisitor) : void {
v.visitDirectory(this);
// no, it's up to the visitor to decide whether to recur on the children
// this.children.forEach((child) => child.accept(v))
}

}

export default Directory
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class DuVisitor implements IFileSystemVisitor {
}
public visitDirectory(d: Directory) : void {
this.nrDirectories++;
d.getChildren().forEach((child) => child.accept(this))
}
public visitLink(l: Link) : void {
this.nrLinks++;
Expand Down
34 changes: 34 additions & 0 deletions all-examples/filesystem-visitor/duvisitor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import File from './file'
import Directory from './directory'
import Link from './link'
import IFileSystemVisitor from './ifilesystemvisitor';

class DuVisitor implements IFileSystemVisitor {

private nrFiles = 0
private nrDirectories = 0
private nrLinks = 0
private totalSize = 0

constructor() { }

public visitFile(f: File): void {
this.nrFiles++;
this.totalSize += f.size();
}
public visitDirectory(d: Directory): void {
this.nrDirectories++;
}
public visitLink(l: Link): void {
this.nrLinks++;
}

public report(): void {
console.log("files: " + this.nrFiles);
console.log("directories: " + this.nrDirectories);
console.log("links: " + this.nrLinks);
console.log("total size: " + this.totalSize);
}
}

export default DuVisitor
20 changes: 20 additions & 0 deletions all-examples/filesystem-visitor/file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Directory from './directory'
import Node from './node'
import IFileSystemVisitor from './ifilesystemvisitor';

class File extends Node {
private content: string

constructor(n: string, p: Directory, content: string){
super(n,p);
this.content = content;
}
public accept(v: IFileSystemVisitor) : void {
v.visitFile(this);
}
public size() : number {
return this.content.length;
}
}

export default File
11 changes: 11 additions & 0 deletions all-examples/filesystem-visitor/ifilesystemvisitor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Directory from './directory';
import Link from './link';
import File from './file'

interface IFileSystemVisitor {
visitFile(f: File) : void;
visitDirectory(d: Directory): void;
visitLink(l: Link): void;
}

export default IFileSystemVisitor
20 changes: 20 additions & 0 deletions all-examples/filesystem-visitor/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Directory from './directory'
import File from './file'
import Link from './link';
import DuVisitor from './duvisitor';

let root = new Directory("");
new File("core", root, "hello");
let usr = new Directory("usr", root);
new File("adm", usr, "there");
new Directory("foo", usr);
new File("bar1", usr, "abcdef");
new File("xbar2", usr, "abcdef");
new File("yybarzz3", usr, "abcdef");
let link = new Link("link", usr, root);
new Link("link2", link, root);

let visitor = new DuVisitor();
root.accept(visitor);
visitor.report();

20 changes: 20 additions & 0 deletions all-examples/filesystem-visitor/link.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Directory from "./directory";
import Node from "./node"
import IFileSystemVisitor from "./ifilesystemvisitor";

class Link extends Node {
private realNode: Node;

constructor(n: string, w: Node, p: Directory){
super(n,p);
this.realNode = w;
}
public getAbsoluteName() : string{
return super.getAbsoluteName() + "@";
}
public accept(v: IFileSystemVisitor) : void {
v.visitLink(this);
}
}

export default Link
22 changes: 22 additions & 0 deletions all-examples/filesystem-visitor/node.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Directory from './directory'
import IFileSystemVisitor from './ifilesystemvisitor';

abstract class Node {
protected name: string;
protected parent: Directory;

constructor(name: string, parent: Directory) {
this.name = name; this.parent = parent;
if (this.parent != null) { this.parent.add(this); }
}
public getAbsoluteName() : string {
if (this.parent != null) {
return this.parent.getAbsoluteName() + this.name;
}
return this.name;
}
public toString() : string { return this.getAbsoluteName(); }
public abstract accept(v: IFileSystemVisitor) : void;
}

export default Node
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading