W5 Flashcards
(16 cards)
The Single Responsibility Principle: SRP
-
Idea: Every class should have a single responsibility.
- Alternative phrasing: A class should only have one reason to change
- An actor causes the change
Actor
Actor: a user of the program or a stakeholder, or a group of such people, or an automated process
Open/Closed Principle (OCP)
Software entities (classes, modules, functions, etc.) should be open for extension but closed for modification.
Liskov Substitution Principle (LSP)
Objects of a superclass should be replaceable with objects of a subclass without altering the correctness of the program.
Example:
A subclass should not change the behavior of the parent class in unexpected ways.
Interface Segregation Principle (ISP)
Clients should not be forced to depend on methods they do not use.
Dependency Inversion Principle (DIP)
High-level modules should not depend on low-level modules. Both should depend on abstractions.
What does “encapsulation” mean? Which of the SOLID principles are related to
encapsulation?
Encapsulation is the idea that we should try to make everything as close to private
as possible so we can make a change to one part of our code without being forced to
change other parts as a result.
- SRP promotes encapsulation by ensuring that each class has a single responsibility, which helps to clearly define the purpose of the class. This reduces the chances of exposing unnecessary details or functionality, maintaining better control over the class’s internal workings.
- OCP encourages extending behavior via abstraction (e.g., using interfaces or base classes) rather than modifying existing code.
- LSP relies on proper encapsulation to ensure that subclasses behave as expected when used in place of their parent class.
- ISP enhances encapsulation by advocating for smaller, more focused interfaces rather than large, general-purpose ones.
- DIP ensures that high-level modules depend on abstractions rather than low-level details. Encapsulation is key here, as it hides the internal workings of low-level modules behind abstractions, allowing high-level modules to remain decoupled and unaware of specific implementations.
What does “High cohesion, loose coupling” mean? Which of the SOLID principles
explicitly agree with this statement?
High cohesion means that all methods within a class are related and work together
to do one thing. This is related (but not the same) as the Single Responsibility
Principle. This is also the Interface Principle which can be re-stated as “Make
your interfaces as cohesive as possible.”
Loose coupling means our classes should be as self-contained as possible and not
depend too much on other classes. That makes it easier to change one part of the
code without requiring changes to other parts as well. This is similar to the Open/
Closed principle which includes the idea of minimizing the amount of code we re-
write.
We have seen many features of Java that agree with the SOLID principles.
Describe five features, one for each SOLID principle that agrees with the
principle
- Every class that is built into java (example: ArrayList) has a single responsibility.
- By having every object inherit from the Object class and the ability to make a variable’s type more abstract than its constructor, we can easily change constructor calls (say ArrayList changed to LinkedList) without re-writing the rest of the program. This follows the Open/Closed Principle which wants us to minimize the amount of re-writing we do.
- Liskov Substitution Principle is followed by every super and subclass built into Java. For example, we can replace an instance of Exception with an instance of IOException.
- Interface Principle says you should have a minimum amount of methods required in each interface. For this reason, there are no methods at all in the Serializable interface.
- Dependency Inversion Principle says we should depend on the more abstract type when given a choice. For this reason, you can write InputStream x = new FileInputStream(); so that the rest of the code doesn’t have to know specifically that the input is coming from a file, which is less abstract than InputStream
What is an Exception in Java?
An object. A subclass of Throwable. It is thrown in exceptional circumstances –
any situation you can predict but cannot prevent. (RuntimeExceptions should be
prevented, so that your program does not throw them again.)
What is the conceptual difference between a “checked” and “unchecked” Exception?
A checked exception causes the compiler to check that anyone calling your method
uses a try and catch block for the exception it might throw. An unchecked exception
will crash your program if thrown because there is no catch block for it.
What is the syntactical (syntax) difference between a “checked” and “unchecked”
Exception?
A checked exception includes “throws ExceptionName” in the signature of the method.
An unchecked exception does not.
Why do we leave RuntimeExceptions unchecked?
They are avoidable, usually with a simple if statement. So we let them crash the
program and print the stack trace to the terminal telling us where to look for the
problem. Then we fix the problem so that this RuntimeException is not thrown again.
Why should we not include as many checked Exceptions as possible in our code?
It gets confusing to read code that always finishes executing methods because an
exception is thrown. Exceptions should only be used in situations we can predict
but not prevent.
When should we catch each exception?
Each exception should be caught in the layer where such information is useful. If a
Use Case Interactor calls the getter for an Entity object and receives an
IndexOutOfBoundsException, it should catch it. This is because Use Case Interactors
are responsible for managing the entities. But the user at the keyboard still needs
to know that something went wrong.
If the Entity was a student’s transcript, then the UseCaseInteractor might catch
the IndexOutOfBoundsException and then, in the catch block, throw an
UnableToLocateTranscriptException to tell the View which message to display to the
user.
What is the purpose of a “finally” block?
This block forces code to be run between the catch block and when the method is
finished executing. Without this block, subsequent code will not run (unless your
catch block is in the main method, which works differently in this case)