Home > Web Front-end > JS Tutorial > (I): Applying the \'Interface Segregation Principle\' with Typescript and Java

(I): Applying the \'Interface Segregation Principle\' with Typescript and Java

Patricia Arquette
Release: 2024-11-27 13:07:14
Original
731 people have browsed it

(I): Aplicando o

Concepts

SOLID is an acronym that represents five fundamental principles of object-oriented programming, proposed by Robert C. Martin - Uncle Bob. Here you can read more about his article.
These principles aim to improve the structure and maintenance of code, making it more flexible, scalable, and easier to understand. Such principles help the programmer to create more organized codes, dividing responsibilities, reducing dependencies, simplifying the refactoring process and promoting code reuse.

The "I" in the acronym stands for "Interface Segregation Principle". The phrase that uncle bob used to define this principle was:

"No customer should be forced to depend on interfaces they do not use"

The Interface Segregation Principle addresses a common problem: excessively large interfaces that force unnecessary implementations into classes that don't need them.

Practical application

Imagine an authentication system in an application, where different methods are used to authenticate a user (e.g., by password, by biometrics, by QR Code).

First, let's look at the application of this class without using the ISP in Java and Typescript:

Java

interface Authenticator {
    boolean authenticateWithPassword(String userId, String password);
    boolean authenticateWithBiometrics(String userId);
    boolean authenticateWithQRCode(String qrCode);
}

class PasswordAuthenticator implements Authenticator {
    @Override
    public boolean authenticateWithPassword(String userId, String password) {
        System.out.println("Authenticating with password...");
        return true;
    }

    @Override
    public boolean authenticateWithBiometrics(String userId) {
        throw new UnsupportedOperationException("Not implemented");
    }

    @Override
    public boolean authenticateWithQRCode(String qrCode) {
        throw new UnsupportedOperationException("Not implemented");
    }
}

Copy after login

Typescript

interface Authenticator {
  authenticateWithPassword(userId: string, password: string): boolean;
  authenticateWithBiometrics(userId: string): boolean;
  authenticateWithQRCode(qrCode: string): boolean;
}

class PasswordAuthenticator implements Authenticator {
  authenticateWithPassword(userId: string, password: string): boolean {
    console.log("Authenticating with password...");
    return true;
  }

  authenticateWithBiometrics(userId: string): boolean {
    throw new Error("Not implemented");
  }

  authenticateWithQRCode(qrCode: string): boolean {
    throw new Error("Not implemented");
  }
}
Copy after login

Problems:

  1. Unused methods: The PasswordAuthenticator class implements methods that do not make sense for its function.
  2. Troublesome maintenance: If the interface changes, all implementing classes need to be changed, even if they do not use the new methods.
  3. Single Responsibility Violation: Classes begin to deal with concerns that should not be theirs.

To solve the problem, we can split the Authenticator interface into smaller, more specific interfaces.

Java

interface PasswordAuth {
    boolean authenticateWithPassword(String userId, String password);
}

interface BiometricAuth {
    boolean authenticateWithBiometrics(String userId);
}

interface QRCodeAuth {
    boolean authenticateWithQRCode(String qrCode);
}

class PasswordAuthenticator implements PasswordAuth {
    @Override
    public boolean authenticateWithPassword(String userId, String password) {
        System.out.println("Authenticating with password...");
        return true;
    }
}

class BiometricAuthenticator implements BiometricAuth {
    @Override
    public boolean authenticateWithBiometrics(String userId) {
        System.out.println("Authenticating with biometrics...");
        return true;
    }
}

class QRCodeAuthenticator implements QRCodeAuth {
    @Override
    public boolean authenticateWithQRCode(String qrCode) {
        System.out.println("Authenticating with QR Code...");
        return true;
    }
}

Copy after login

Typescript

interface PasswordAuth {
  authenticateWithPassword(userId: string, password: string): boolean;
}

interface BiometricAuth {
  authenticateWithBiometrics(userId: string): boolean;
}

interface QRCodeAuth {
  authenticateWithQRCode(qrCode: string): boolean;
}

class PasswordAuthenticator implements PasswordAuth {
  authenticateWithPassword(userId: string, password: string): boolean {
    console.log("Authenticating with password...");
    return true;
  }
}

class BiometricAuthenticator implements BiometricAuth {
  authenticateWithBiometrics(userId: string): boolean {
    console.log("Authenticating with biometrics...");
    return true;
  }
}

class QRCodeAuthenticator implements QRCodeAuth {
  authenticateWithQRCode(qrCode: string): boolean {
    console.log("Authenticating with QR Code...");
    return true;
  }
}
Copy after login

Benefits of Refactoring

  1. Specific interfaces: Each class implements only the methods it actually uses.
  2. Flexibility: Adding new authentication methods or modes does not impact existing implementations.
  3. Simpler maintenance: Reduces the impact of code changes, avoiding unnecessary refactorings.

Conclusion

The above is the detailed content of (I): Applying the \'Interface Segregation Principle\' with Typescript and Java. For more information, please follow other related articles on the PHP Chinese website!

source:dev.to
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template