JavaScript and TypeScript course Β· Module 9: Design Patterns and Architecture
Final Project: Jurassic Park Management System
In this lesson8
Welcome to the Jurassic Park genetic laboratory! After a long journey through the world of JavaScript, it's time for the challenge that wraps up this module. Dr. Henry Wu, the park's chief geneticist, entrusts you with creating a comprehensive management system that will oversee all aspects of the park's operation - from monitoring dinosaurs to managing visitor safety.
Project goal
Your task is to create an advanced JavaScript application that integrates all the technologies you've learned into one cohesive system. This will be your magnum opus - proof that you've mastered the art of JavaScript programming.
Functional requirements of the system
1. Dinosaur management system
Your system must enable:
1// Example dinosaur data structure
2const dinosaurSpecies = {
3 id: 'trex-001',
4 name: 'Tyrannosaurus Rex',
5 species: 'T-Rex',
6 genome: {
7 dnaSequence: '4A7B...9F2E', // DNA sequence
8 modifications: ['enhanced-strength', 'reduced-aggression'],
9 purity: 0.92, // 92% original DNA
10 gapsFilled: ['amphibian-dna', 'bird-dna']
11 },
12 physicalTraits: {
13 height: 5.6, // meters
14 weight: 8500, // kg
15 length: 12.8, // meters
16 age: 4, // years
17 healthStatus: 'excellent'
18 },
19 behavior: {
20 aggressionLevel: 7, // 1-10
21 intelligence: 8,
22 socialBehavior: 'territorial',
23 huntingPattern: 'ambush-predator'
24 },
25 habitat: {
26 enclosureId: 'sector-7',
27 temperature: { min: 18, max: 28, current: 24 },
28 humidity: { min: 60, max: 80, current: 72 },
29 terrainType: 'forest-plains'
30 },
31 status: 'active' // active, sedated, medical-care, quarantine
32};2. Security monitoring system
1// Security system structure
2const securitySystem = {
3 alerts: {
4 breach: false,
5 evacuation: false,
6 containmentFailure: false,
7 emergencyProtocol: false
8 },
9 sensors: [
10 {
11 id: 'fence-sensor-001',
12 type: 'perimeter',
13 location: 'sector-7-north',
14 status: 'operational',
15 lastReading: Date.now(),
16 voltage: 10000 // fence voltage in volts
17 },
18 {
19 id: 'motion-detector-034',
20 type: 'motion',
21 location: 'visitor-center',
22 status: 'operational',
23 sensitivity: 'high',
24 detectedMovement: false
25 }
26 ],
27 accessControl: {
28 keyCards: new Map(), // Card ID -> access level
29 restrictedAreas: ['genetic-lab', 'control-room', 'medical-bay'],
30 emergencyOverride: false
31 }
32};3. Visitor management system
1// Visitor management system
2class VisitorManagementSystem {
3 constructor() {
4 this.visitors = new Map();
5 this.tours = new Map();
6 this.emergencyContactList = [];
7 this.evacuationProcedures = [];
8 }
9
10 registerVisitor(visitorData) {
11 const visitor = {
12 id: this.generateVisitorId(),
13 personalData: {
14 name: visitorData.name,
15 age: visitorData.age,
16 emergencyContact: visitorData.emergencyContact,
17 medicalConditions: visitorData.medicalConditions || [],
18 insurancePolicy: visitorData.insurancePolicy
19 },
20 visit: {
21 arrivalTime: new Date(),
22 departureTime: null,
23 tourType: visitorData.tourType, // 'standard', 'vip', 'research'
24 groupId: visitorData.groupId,
25 currentLocation: 'entrance',
26 visitedAreas: ['entrance']
27 },
28 safety: {
29 waiverSigned: false,
30 briefingCompleted: false,
31 emergencyProtocolsExplained: false,
32 trackingDevice: null
33 }
34 };
35
36 this.visitors.set(visitor.id, visitor);
37 return visitor.id;
38 }
39
40 trackVisitorLocation(visitorId, newLocation) {
41 const visitor = this.visitors.get(visitorId);
42 if (visitor) {
43 visitor.visit.currentLocation = newLocation;
44 visitor.visit.visitedAreas.push(newLocation);
45 this.validateSafetyProtocols(visitor);
46 }
47 }
48}4. Genetic laboratory system
1// Genetic laboratory system
2class GeneticLaboratory {
3 constructor() {
4 this.dnaLibrary = new Map();
5 this.activeExperiments = [];
6 this.incubators = [];
7 this.sequencingMachines = [];
8 }
9
10 analyzeDNA(sampleId, dnaSequence) {
11 const analysis = {
12 sampleId,
13 sequenceLength: dnaSequence.length,
14 gcContent: this.calculateGCContent(dnaSequence),
15 mutations: this.detectMutations(dnaSequence),
16 viability: this.assessViability(dnaSequence),
17 recommendedModifications: [],
18 timestamp: new Date()
19 };
20
21 return analysis;
22 }
23
24 createNewSpecimen(parentDNA, modifications = []) {
25 const baseGenome = this.reconstructGenome(parentDNA);
26 const modifiedGenome = this.applyModifications(baseGenome, modifications);
27
28 const specimen = {
29 id: this.generateSpecimenId(),
30 genome: modifiedGenome,
31 generation: this.getParentGeneration(parentDNA) + 1,
32 created: new Date(),
33 status: 'developing',
34 expectedHatchTime: this.calculateHatchTime(modifiedGenome),
35 parentSpecimens: [parentDNA.id]
36 };
37
38 return this.initiateIncubation(specimen);
39 }
40}Technical requirements
1. Application architecture
Your application must use:
- Module Pattern or ES6 Modules for code organization
- Observer Pattern for communication between components
- Factory Pattern for creating dinosaur and visitor objects
- Singleton Pattern for critical systems (security, main database)
1// Example of modular architecture
2// modules/ParkCore.js
3class ParkCore {
4 constructor() {
5 if (ParkCore.instance) {
6 return ParkCore.instance;
7 }
8
9 this.systems = {
10 security: new SecuritySystem(),
11 genetic: new GeneticLaboratory(),
12 visitors: new VisitorManagementSystem(),
13 dinosaurs: new DinosaurRegistry(),
14 weather: new WeatherMonitoring(),
15 power: new PowerGrid()
16 };
17
18 this.eventBus = new EventBus();
19 this.setupSystemCommunication();
20
21 ParkCore.instance = this;
22 }
23
24 setupSystemCommunication() {
25 // Communication between systems via event bus
26 this.eventBus.subscribe('security.breach', (data) => {
27 this.systems.visitors.initiateEvacuation(data.location);
28 this.systems.dinosaurs.activateContainmentProtocol();
29 });
30
31 this.eventBus.subscribe('dinosaur.escaped', (data) => {
32 this.systems.security.raiseAlert('containment-failure', data);
33 this.systems.visitors.redirectToSafeZones(data.dangerRadius);
34 });
35 }
36}2. Data management
1// Data management system with localStorage and IndexedDB
2class DataManager {
3 constructor() {
4 this.localDB = new LocalDatabase('park-data');
5 this.cache = new Map();
6 this.syncQueue = [];
7 }
8
9 async saveDinosaurData(dinosaur) {
10 try {
11 // Save to cache
12 this.cache.set(dinosaur.id, dinosaur);
13
14 // Save to localStorage as backup
15 localStorage.setItem(`dino_${dinosaur.id}`, JSON.stringify(dinosaur));
16
17 // Save to IndexedDB for larger data
18 await this.localDB.store('dinosaurs', dinosaur);
19
20 // Add to synchronization queue with server
21 this.queueForSync('dinosaurs', dinosaur.id, 'update');
22
23 } catch (error) {
24 console.error('Error saving dinosaur data:', error);
25 throw new DataError('Failed to save dinosaur data');
26 }
27 }
28
29 async loadParkState() {
30 try {
31 const [dinosaurs, visitors, security] = await Promise.all([
32 this.localDB.getAll('dinosaurs'),
33 this.localDB.getAll('visitors'),
34 this.localDB.get('security', 'current-state')
35 ]);
36
37 return {
38 dinosaurs: dinosaurs || [],
39 visitors: visitors || [],
40 security: security || this.getDefaultSecurityState()
41 };
42 } catch (error) {
43 console.error('Error loading park state:', error);
44 return this.getEmergencyFallbackState();
45 }
46 }
47}3. User interface
Your system must include:
- Main dashboard with an overview of all systems
- Dinosaur panel with a list, details, and management capabilities
- Security monitor with alerts and system status
- Visitor panel with a list of active tours
- Genetic laboratory with DNA analysis tools
- Reporting system with charts and statistics
1// User interface example
2class ParkInterface {
3 constructor(parkCore) {
4 this.park = parkCore;
5 this.currentView = 'dashboard';
6 this.refreshInterval = null;
7 this.setupEventListeners();
8 }
9
10 render() {
11 const app = document.getElementById('park-app');
12 app.innerHTML = `
13 <header class="park-header">
14 <h1>Jurassic Park Management System</h1>
15 <div class="system-status">${this.renderSystemStatus()}</div>
16 </header>
17
18 <nav class="park-navigation">
19 ${this.renderNavigation()}
20 </nav>
21
22 <main class="park-content">
23 ${this.renderCurrentView()}
24 </main>
25
26 <aside class="alerts-panel">
27 ${this.renderAlerts()}
28 </aside>
29 `;
30
31 this.bindEvents();
32 }
33
34 renderDinosaurPanel() {
35 const dinosaurs = this.park.systems.dinosaurs.getAll();
36
37 return `
38 <div class="dinosaur-panel">
39 <h2>Dinosaur Management</h2>
40
41 <div class="dinosaur-grid">
42 ${dinosaurs.map(dino => `
43 <div class="dinosaur-card" data-id="${dino.id}">
44 <div class="dino-header">
45 <h3>${dino.name}</h3>
46 <span class="status ${dino.status}">${dino.status}</span>
47 </div>
48
49 <div class="dino-stats">
50 <div class="stat">
51 <label>Age:</label>
52 <span>${dino.physicalTraits.age} years</span>
53 </div>
54 <div class="stat">
55 <label>Health:</label>
56 <span>${dino.physicalTraits.healthStatus}</span>
57 </div>
58 <div class="stat">
59 <label>Location:</label>
60 <span>${dino.habitat.enclosureId}</span>
61 </div>
62 </div>
63
64 <div class="dino-actions">
65 <button data-action="feed">Feed</button>
66 <button data-action="checkup">Checkup</button>
67 <button data-action="relocate">Relocate</button>
68 </div>
69 </div>
70 `).join('')}
71 </div>
72
73 <button class="add-dinosaur-btn" data-action="add-dinosaur">
74 + Add new dinosaur
75 </button>
76 </div>
77 `;
78 }
79
80 bindEvents() {
81 // One listener on the container (event delegation): in an onclick attribute "this" would be the button, not ParkInterface
82 document.getElementById('park-app').onclick = (event) => {
83 const button = event.target.closest('[data-action]');
84 if (!button) return;
85 const id = button.closest('.dinosaur-card')?.dataset.id;
86 const actions = {
87 feed: () => this.feedDinosaur(id),
88 checkup: () => this.medicateCheckup(id),
89 relocate: () => this.relocateDinosaur(id),
90 'add-dinosaur': () => this.showAddDinosaurForm()
91 };
92 actions[button.dataset.action]?.();
93 };
94 }
95}4. Emergency situation handling
1// Emergency response system
2class EmergencyResponseSystem {
3 constructor(parkCore) {
4 this.park = parkCore;
5 this.emergencyLevel = 0; // 0-5, where 5 is the highest
6 this.activeProtocols = [];
7 this.evacuationRoutes = this.loadEvacuationRoutes();
8 }
9
10 handleEmergency(type, severity, location, additionalData = {}) {
11 const emergency = {
12 id: this.generateEmergencyId(),
13 type, // 'containment-breach', 'power-failure', 'weather-emergency', 'medical'
14 severity, // 1-5
15 location,
16 timestamp: new Date(),
17 status: 'active',
18 data: additionalData
19 };
20
21 // Automatic procedures depending on type and severity
22 switch (type) {
23 case 'containment-breach':
24 this.handleContainmentBreach(emergency);
25 break;
26 case 'power-failure':
27 this.handlePowerFailure(emergency);
28 break;
29 case 'weather-emergency':
30 this.handleWeatherEmergency(emergency);
31 break;
32 case 'medical':
33 this.handleMedicalEmergency(emergency);
34 break;
35 default:
36 this.handleGenericEmergency(emergency);
37 }
38
39 return emergency.id;
40 }
41
42 handleContainmentBreach(emergency) {
43 const { location, data } = emergency;
44
45 // 1. Immediate lockdown of affected sector
46 this.park.systems.security.lockdownSector(location);
47
48 // 2. Activate evacuation protocol for visitors in the danger zone
49 const dangerZone = this.calculateDangerZone(location, data.dinosaurType);
50 this.park.systems.visitors.evacuateZone(dangerZone);
51
52 // 3. Deploy response team
53 this.deployResponseTeam('containment', location, data);
54
55 // 4. Notify all systems
56 this.park.eventBus.publish('emergency.containment-breach', {
57 location,
58 dangerZone,
59 estimatedContainmentTime: this.estimateContainmentTime(data.dinosaurType)
60 });
61
62 // 5. Automatic safety protocols
63 this.activateEmergencyProtocol('Code Red - Containment Breach');
64 }
65}Advanced features
1. Real-time simulation
1// Time simulation and life cycle system
2class TimeSimulation {
3 constructor() {
4 this.gameTime = new Date();
5 this.timeMultiplier = 1; // 1 = real time, 60 = 1 minute = 1 hour
6 this.isRunning = false;
7 this.events = [];
8 }
9
10 start() {
11 this.isRunning = true;
12 this.simulationLoop();
13 }
14
15 simulationLoop() {
16 if (!this.isRunning) return;
17
18 // Update simulation time
19 this.gameTime = new Date(this.gameTime.getTime() + (1000 * this.timeMultiplier));
20
21 // Check scheduled events
22 this.processScheduledEvents();
23
24 // Simulate natural processes
25 this.simulateNaturalProcesses();
26
27 // Next iteration in one second
28 setTimeout(() => this.simulationLoop(), 1000);
29 }
30
31 simulateNaturalProcesses() {
32 // Dinosaur aging
33 this.ageDinosaurs();
34
35 // Weather changes
36 this.updateWeather();
37
38 // Resource consumption (energy, food)
39 this.consumeResources();
40
41 // Natural dinosaur behaviors
42 this.simulateDinosaurBehavior();
43 }
44}2. AI system for dinosaurs
1// Dinosaur artificial intelligence
2class DinosaurAI {
3 constructor(dinosaur) {
4 this.dinosaur = dinosaur;
5 this.currentState = 'idle';
6 this.needs = {
7 hunger: 50,
8 thirst: 30,
9 social: 70,
10 territory: 80,
11 reproduction: 20
12 };
13 this.decisionTree = this.buildDecisionTree();
14 }
15
16 makeDecision() {
17 const context = this.gatherEnvironmentalData();
18 const urgentNeed = this.findMostUrgentNeed();
19
20 const decision = this.decisionTree.evaluate(urgentNeed, context);
21
22 return this.executeDecision(decision);
23 }
24
25 buildDecisionTree() {
26 return {
27 evaluate: (need, context) => {
28 if (need === 'hunger' && this.needs.hunger > 80) {
29 return this.findFood(context);
30 }
31
32 if (need === 'social' && this.dinosaur.behavior.socialBehavior === 'pack') {
33 return this.seekPackMembers(context);
34 }
35
36 if (need === 'territory' && context.intruders.length > 0) {
37 return this.defendTerritory(context.intruders);
38 }
39
40 return { action: 'wander', target: this.chooseRandomLocation() };
41 }
42 };
43 }
44}Evaluation criteria
Your project will be evaluated according to the following criteria:
1. Functionality (30%)
- All required systems work correctly
- Error handling and edge cases
- Intuitive user interface
- Application responsiveness
2. Code and architecture (25%)
- Readable, well-commented code
- Proper use of design patterns
- Modular application structure
- Following JavaScript best practices
3. Advanced features (20%)
- Real-time system implementation
- AI for dinosaurs
- Advanced data management
- Reporting and analytics system
4. Creativity and innovation (15%)
- Unique features and solutions
- Interactive UI/UX elements
- Interesting extensions of the dinosaur theme
- Implementation of additional systems
5. Testing and documentation (10%)
- Unit tests for key functions
- API and architecture documentation
- User manual
- Code comments
Bonus challenges (extra points)
1. Genetic system with real DNA logic
Implement a real DNA sequence analysis system with:
- Genetic mutation algorithms
- Cross-species DNA breeding system
- Predicting physical traits based on genotype
- Simulating trait inheritance across generations
2. Multiplayer and real-time communication
Add multi-user functionality:
- WebSocket for real-time communication
- Shared park management by multiple users
- Chat between park managers
- State synchronization between clients
3. Advanced API and integrations
Connect with external services:
- Real weather data
- User geolocation
- Payment system for tickets
- Calendar reservation integration
4. Machine Learning and prediction
Add machine learning elements:
- Predicting dinosaur behavior
- Optimizing feeding schedules
- Analyzing visitor patterns
- Predicting system failures
Getting started
Step 1: Planning
- Draw a system architecture diagram
- Define main modules and their responsibilities
- Plan the data structure
- Create a list of MVP (Minimum Viable Product) features
Step 2: Implementing MVP
- Create the basic application structure
- Implement core classes (ParkCore, DataManager)
- Add the basic user interface
- Connect modules via event bus
Step 3: Expanding functionality
- Add each system individually
- Test integration between systems
- Implement advanced features
- Optimize performance
Step 4: Finalization
- Add error handling
- Write tests
- Create documentation
- Conduct final testing
Technical tips
File structure
1jurassic-park-system/
2βββ index.html
3βββ css/
4β βββ main.css
5β βββ dashboard.css
6β βββ components.css
7βββ js/
8β βββ core/
9β β βββ ParkCore.js
10β β βββ EventBus.js
11β β βββ DataManager.js
12β βββ systems/
13β β βββ SecuritySystem.js
14β β βββ DinosaurRegistry.js
15β β βββ VisitorManager.js
16β β βββ GeneticLab.js
17β βββ ui/
18β β βββ Dashboard.js
19β β βββ DinosaurPanel.js
20β β βββ SecurityMonitor.js
21β βββ utils/
22β β βββ helpers.js
23β β βββ validators.js
24β βββ app.js
25βββ data/
26β βββ dinosaurs.json
27β βββ species-data.json
28β βββ default-config.json
29βββ tests/
30 βββ core.test.js
31 βββ systems.test.js
32 βββ integration.test.jsExample application initialization
1// app.js - main application file
2document.addEventListener('DOMContentLoaded', async () => {
3 try {
4 // Initialize system
5 const park = new ParkCore();
6 await park.initialize();
7
8 // Load data
9 const dataManager = new DataManager();
10 const savedState = await dataManager.loadParkState();
11
12 if (savedState) {
13 await park.loadState(savedState);
14 } else {
15 await park.initializeDefaultState();
16 }
17
18 // Initialize interface
19 const ui = new ParkInterface(park);
20 ui.render();
21
22 // Start simulation
23 const simulation = new TimeSimulation(park);
24 simulation.start();
25
26 console.log('Jurassic Park Management System started successfully!');
27
28 } catch (error) {
29 console.error('System initialization error:', error);
30 showErrorPage('Failed to start the park management system');
31 }
32});This is your big end-of-module challenge, young programmer! It's time to show what you have learned and create something truly exceptional. Dr. Wu and the entire genetic laboratory are counting on you!
Good luck building the future of Jurassic Park!
Code for this lesson: index.js
1// Dinosaur AI System
2// Exercise: Implement a needs and behavior system
3
4class DinosaurAI {
5 constructor(name, species) {
6 this.name = name;
7 this.species = species;
8 this.needs = { hunger: 50, energy: 80, social: 60 };
9 this.behavior = "idle";
10 }
11
12 // Implement the methods:
13 // updateNeeds() - update needs (random changes)
14 // decideBehavior() - make a behavior decision based on needs
15 // getStatus() - return the dinosaur's status
16
17 updateNeeds() {
18 // Your code here
19 }
20
21 decideBehavior() {
22 // Your code here
23 }
24
25 getStatus() {
26 // Your code here
27 }
28}
29
30const rex = new DinosaurAI("Blue", "Velociraptor");
31console.log("Dinosaur AI:", rex.name, "Status:", rex.behavior);Spotted a mistake in this lesson?