Created
December 22, 2017 20:40
-
-
Save Beraliv/2dfe3b4c696cf17eabc066ff5a7a7497 to your computer and use it in GitHub Desktop.
Car drive history
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const CarFactory = ({ name }) => { | |
let distancePassed = 0; | |
let driveHistory = []; | |
let car = { | |
name, | |
beep({ message = '' } = {}) { | |
console.log(`${name}: Beeeeep! ${message}`); | |
}, | |
drive({ distance }) { | |
this.beep(); | |
distancePassed += distance; | |
driveHistory.push(() => ({ | |
time: new Date().getTime(), | |
currentDistance: distance, | |
overallDistance: distancePassed, | |
})); | |
console.log(`Done. Kilometers passed: ${distance}. Overall: ${distancePassed}`); | |
}, | |
}; | |
Object.defineProperty(car, 'driveHistory', { | |
enumerable: false, | |
configurable: false, | |
writable: false, | |
value: () => driveHistory, | |
}); | |
return car; | |
}; | |
const HackerFactory = () => ({ | |
hackCar: ({ car }) => ({ | |
...car, | |
driveHistory: () => car.driveHistory().map((historyRecord, index) => () => ({ | |
time: historyRecord().time, | |
currentDistance: 100, | |
overallDistance: 100 * (index + 1), | |
})), | |
}), | |
}); | |
const OwnerFactory = ({ car, driveHistory, hacker = HackerFactory() }) => { | |
let configuredCar = car; | |
return { | |
sellCar({ customer }) { | |
console.log('Enough. I want to sell this car.'); | |
if (customer.buyCar({ car: configuredCar })) { | |
console.log('Yay, I\'m happy! I sold my old car!'); | |
return; | |
} | |
console.log("Aha. Let's hack this car and try to sell it again."); | |
configuredCar = hacker.hackCar({ | |
car: configuredCar, | |
}); | |
this.sellCar({ customer }); | |
}, | |
useCar() { | |
for (const distance of driveHistory) { | |
configuredCar.drive({ distance }); | |
} | |
}, | |
getCar() { | |
return configuredCar; | |
}, | |
}; | |
}; | |
const CustomerFactory = ({ criteria = (allDistance) => ({ allDistance }) < 100000 } = {}) => ({ | |
buyCar: ({ car }) => criteria({ | |
allDistance: car.driveHistory().reduce((sum, f) => { | |
let { overallDistance, currentDistance } = f(); | |
return sum + overallDistance - currentDistance; | |
}, 0) | |
}) | |
? console.log('I don\'t want to buy an old car') || true | |
: console.log('OK! I like your car. I buy it.') || false, | |
}); | |
let superCar = CarFactory({ name: 'SuperCar' }); | |
let owner = OwnerFactory({ | |
car: superCar, | |
driveHistory: [18000, 22500, 98118], | |
}); | |
owner.useCar(); | |
owner.sellCar({ | |
customer: CustomerFactory() | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment