The goal of this kata is to learn and apply concepts from Domain-driven Design and Layered Architecture to some existing code.
- Checkout the project
git clone https://github.com/alonsogarciapablo/vue-js-refactoring-kata.git
- Install dependencies
npm install
- Run the tests
npm run test
- Run the app
npm run serve- You're ready to go! 👏
- Define a
RegisterUserclass with an empty constructor and anexecutemethod. - Copy the content of the
submitfunction to the newexecutemethod. Define a parameter for each of the missing variables (eg: refs) and define a variable to hold the return value (hint: the errors), removing any Vue.js code (eg: refs). - Create an instance of the
RegisterUserclass and use it in the submit function. - Extract the new class to its own file:
src/application/use-cases/register-user.ts. - Take a moment to think how much easier it would be to replace Vue.js with something else now.
class RegisterUser {
constructor(...) {
…
}
execute(): ??? {
…
}
}Solution: https://github.com/alonsogarciapablo/vue-js-refactoring-kata/compare/main...refactor-step-1
- Define a
UsersRepositoryinterface in the file whereInMemoryUsersRepositoryis defined. - Make
InMemoryUserRepositoryimplement the newUserRepositoryinterface. - Extract
UserRepositoryto its own file:src/domain/repositories/users-repository.ts. - Use
UserRepositoryinRegisterUser. - Rename
inMemoryUsersRepositorytousersRepositoryinSignupView. - Use App-level provide to inject the
UserRepositoryinSignupView. Mock the provide/inject using global.provide in the tests. - Take a moment to think how easy it’d be to implement and use a different
UserRepository.
interface UsersRepository {
add: (user: User) => void
…
}
class InMemoryUsersRepository
implements UsersRepository {
…
}
Solution: https://github.com/alonsogarciapablo/vue-js-refactoring-kata/compare/refactor-step-1...refactor-step-2- Define an empty
Userclass with aname,email,birthDateandencryptedPasswordattributes. - Create an instance of the class.
- Define a
validatemethod that returns an empty list validation errors. - Append the errors to the collection of errors in the view.
- One by one, move validations* to the
Userclass. - Extract the
Userclass to its own file:src/domain/models/user.ts. - Use
UserininMemoryUsersRepository,UsersRepositoryand the tests.
*
class User {
…
constructor(...) {
…
}
validate(): Array<string> {
…
}
}- Define an empty
Emailclass. - Create an instance of the class.
- Define a
validatemethod that returns validation errors. - Append email errors to the collection of errors in the
Userclass. - Move email validations to the
Emailclass. - Extract the
Emailclass to its own file:src/domain/models/email.ts. - Move the instantiation of the
Emailto theUserconstructor
class Email {
constructor(...) {
…
}
validate(): Array<string> {
…
}
}- Define an empty
UserRegistrationServiceclass. - Create an instance of the class in the view.
- Define an
isEmailTakenmethod that returns a boolean. - Implement the
isEmailTakenmethod (you will need to inject some dependencies first). - Use the new service/method in the view.
- Extract the
UserRegistrationServiceclass to its own file:src/domain/services/user-registration-service.ts.
class UserRegistrationService {
constructor(...) {
…
}
isEmailTaken(email: string): boolean {
…
}
}You made it! 👏
Full solution: https://github.com/alonsogarciapablo/vue-js-refactoring-kata/compare/main...refactor