Add all 23 GoF design pattern implementations
This commit is contained in:
26
03-behavioral/visitor/AreaCalculator.java
Normal file
26
03-behavioral/visitor/AreaCalculator.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package visitor;
|
||||
|
||||
/**
|
||||
* Concrete Visitor 1 — calculates area for each shape type.
|
||||
* Area formulas live here, not scattered across shape classes.
|
||||
*/
|
||||
public class AreaCalculator implements ShapeVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(Circle c) {
|
||||
double area = Math.PI * c.getRadius() * c.getRadius();
|
||||
System.out.printf(" Area of %s = %.2f%n", c.getName(), area);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Rectangle r) {
|
||||
double area = r.getWidth() * r.getHeight();
|
||||
System.out.printf(" Area of %s = %.2f%n", r.getName(), area);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Triangle t) {
|
||||
double area = 0.5 * t.getBase() * t.getHeight();
|
||||
System.out.printf(" Area of %s = %.2f%n", t.getName(), area);
|
||||
}
|
||||
}
|
||||
9
03-behavioral/visitor/Circle.java
Normal file
9
03-behavioral/visitor/Circle.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package visitor;
|
||||
|
||||
public class Circle implements Shape {
|
||||
private final double radius;
|
||||
public Circle(double radius) { this.radius = radius; }
|
||||
public double getRadius() { return radius; }
|
||||
@Override public String getName() { return "Circle(r=" + radius + ")"; }
|
||||
@Override public void accept(ShapeVisitor visitor) { visitor.visit(this); }
|
||||
}
|
||||
38
03-behavioral/visitor/Main.java
Normal file
38
03-behavioral/visitor/Main.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package visitor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Visitor Design Pattern — Runnable Demo
|
||||
* Run: javac visitor/*.java -d out/visitor && java -cp out/visitor visitor.Main
|
||||
* Article: https://ankurm.com/visitor-design-pattern-java/
|
||||
*/
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("=== Visitor Design Pattern Demo ===\n");
|
||||
|
||||
List<Shape> shapes = List.of(
|
||||
new Circle(5),
|
||||
new Rectangle(4, 6),
|
||||
new Triangle(3, 8)
|
||||
);
|
||||
|
||||
System.out.println("-- Area Calculator Visitor --");
|
||||
ShapeVisitor areaCalc = new AreaCalculator();
|
||||
for (Shape shape : shapes) {
|
||||
shape.accept(areaCalc);
|
||||
}
|
||||
|
||||
System.out.println("\n-- Perimeter Calculator Visitor --");
|
||||
ShapeVisitor perimCalc = new PerimeterCalculator();
|
||||
for (Shape shape : shapes) {
|
||||
shape.accept(perimCalc);
|
||||
}
|
||||
|
||||
System.out.println("\n-- Key insight --");
|
||||
System.out.println("Added PerimeterCalculator without touching Shape, Circle, Rectangle, Triangle.");
|
||||
System.out.println("To add another operation: write one new Visitor class.");
|
||||
|
||||
System.out.println("\n=== Demo complete ===");
|
||||
}
|
||||
}
|
||||
28
03-behavioral/visitor/PerimeterCalculator.java
Normal file
28
03-behavioral/visitor/PerimeterCalculator.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package visitor;
|
||||
|
||||
/**
|
||||
* Concrete Visitor 2 — calculates perimeter.
|
||||
* Adding this visitor added zero code to Shape, Circle, Rectangle, Triangle.
|
||||
*/
|
||||
public class PerimeterCalculator implements ShapeVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(Circle c) {
|
||||
double p = 2 * Math.PI * c.getRadius();
|
||||
System.out.printf(" Perimeter of %s = %.2f%n", c.getName(), p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Rectangle r) {
|
||||
double p = 2 * (r.getWidth() + r.getHeight());
|
||||
System.out.printf(" Perimeter of %s = %.2f%n", r.getName(), p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Triangle t) {
|
||||
// Simplified: assume isoceles — base + 2 equal sides approximated
|
||||
double side = Math.sqrt(Math.pow(t.getBase() / 2, 2) + Math.pow(t.getHeight(), 2));
|
||||
double p = t.getBase() + 2 * side;
|
||||
System.out.printf(" Perimeter of %s = %.2f%n", t.getName(), p);
|
||||
}
|
||||
}
|
||||
33
03-behavioral/visitor/README.md
Normal file
33
03-behavioral/visitor/README.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Visitor Design Pattern — Java Example
|
||||
|
||||
**Pattern:** Behavioral → Visitor
|
||||
**Article:** https://ankurm.com/visitor-design-pattern-java/
|
||||
|
||||
## What this example shows
|
||||
|
||||
A shape hierarchy that never changes, with operations added as separate visitor classes instead of methods on each shape. `ShapeVisitor` declares one `visit()` overload per concrete type. `Shape` declares `accept(ShapeVisitor)` — the double-dispatch trick: the shape hands itself to the visitor as a concretely-typed `this`, so overload resolution picks the right `visit()` method with no `instanceof` checks anywhere. `Circle`, `Rectangle`, and `Triangle` are plain data holders that know nothing about area or perimeter. `AreaCalculator` and `PerimeterCalculator` are two concrete visitors — adding the second one required zero changes to any shape class. `Main` runs both visitors across the same three shapes.
|
||||
|
||||
## How to run
|
||||
|
||||
```bash
|
||||
javac visitor/*.java -d out/visitor
|
||||
java -cp out/visitor visitor.Main
|
||||
```
|
||||
|
||||
Requires Java 25.
|
||||
|
||||
## Post Section ↔ File Mapping
|
||||
|
||||
| Post Section | File(s) |
|
||||
|---|---|
|
||||
| Implementation: Shape Geometry Operations — the Visitor interface | `ShapeVisitor.java` |
|
||||
| Implementation: Shape Geometry Operations — the Element interface | `Shape.java` |
|
||||
| Implementation: Shape Geometry Operations — Circle | `Circle.java` |
|
||||
| Implementation: Shape Geometry Operations — Rectangle | `Rectangle.java` |
|
||||
| Implementation: Shape Geometry Operations — Triangle | `Triangle.java` |
|
||||
| Implementation: Shape Geometry Operations — AreaCalculator | `AreaCalculator.java` |
|
||||
| Implementation: Shape Geometry Operations — PerimeterCalculator | `PerimeterCalculator.java` |
|
||||
| Implementation: Shape Geometry Operations — wiring it together | `Main.java` |
|
||||
|
||||
Article: https://ankurm.com/visitor-design-pattern-java/
|
||||
All patterns: https://ankurm.com/design-patterns-java/
|
||||
10
03-behavioral/visitor/Rectangle.java
Normal file
10
03-behavioral/visitor/Rectangle.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package visitor;
|
||||
|
||||
public class Rectangle implements Shape {
|
||||
private final double width, height;
|
||||
public Rectangle(double width, double height) { this.width = width; this.height = height; }
|
||||
public double getWidth() { return width; }
|
||||
public double getHeight() { return height; }
|
||||
@Override public String getName() { return "Rectangle(" + width + "x" + height + ")"; }
|
||||
@Override public void accept(ShapeVisitor visitor) { visitor.visit(this); }
|
||||
}
|
||||
7
03-behavioral/visitor/Shape.java
Normal file
7
03-behavioral/visitor/Shape.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package visitor;
|
||||
|
||||
/** Element interface — accepts a visitor */
|
||||
public interface Shape {
|
||||
void accept(ShapeVisitor visitor);
|
||||
String getName();
|
||||
}
|
||||
8
03-behavioral/visitor/ShapeVisitor.java
Normal file
8
03-behavioral/visitor/ShapeVisitor.java
Normal file
@@ -0,0 +1,8 @@
|
||||
package visitor;
|
||||
|
||||
/** Visitor interface — one visit() method per concrete element type */
|
||||
public interface ShapeVisitor {
|
||||
void visit(Circle circle);
|
||||
void visit(Rectangle rectangle);
|
||||
void visit(Triangle triangle);
|
||||
}
|
||||
10
03-behavioral/visitor/Triangle.java
Normal file
10
03-behavioral/visitor/Triangle.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package visitor;
|
||||
|
||||
public class Triangle implements Shape {
|
||||
private final double base, height;
|
||||
public Triangle(double base, double height) { this.base = base; this.height = height; }
|
||||
public double getBase() { return base; }
|
||||
public double getHeight() { return height; }
|
||||
@Override public String getName() { return "Triangle(b=" + base + ",h=" + height + ")"; }
|
||||
@Override public void accept(ShapeVisitor visitor) { visitor.visit(this); }
|
||||
}
|
||||
Reference in New Issue
Block a user