- Software development paradigm
- We should represent our system concepts using classes
- Classes deals with common behaviour to all of its different instances (objects):
- Objects have their own memory
- Object communicate between them sending and receiving messages
- When do you use each one?
- Guilt presumption
- Simplify our classes API (exposed methods) => Easier to understand, easier to be SRP compliant, avoid having to maintain public methods because others are coupled to them
- Question:
- Which would be the output of the
Child#visibilityTestmethod? - Solution:
ChildShould. Possible answers:
- Which would be the output of the
"Child#privateMethod Child#protectedMethod Child#publicMethod" // a
"Parent#privateMethod Child#protectedMethod Child#publicMethod" // b
"Parent#privateMethod Parent#protectedMethod Child#publicMethod" // c
"Parent#privateMethod Child#protectedMethod Parent#publicMethod" // d
"Parent#privateMethod Parent#protectedMethod Parent#publicMethod" // e
// It doesn't compile // f
- What is it for?
- Question:
- Which would be the output for the following
getTotalcalls? - Solution:
CounterShould. Possible answers:
- Which would be the output for the following
CountercounterA = newCounter();
CountercounterB = newCounter();
CountercounterC = newCounter();
counterA.increaseTotal();
counterA.increaseTotal();
counterA.increaseTotal();
counterB.increaseTotal();
counterB.increaseTotal();
counterC.increaseTotal();
// a:counterA.getTotal(); // 0counterB.getTotal(); // 0counterC.getTotal(): // 0// b:counterA.getTotal(); // 6counterB.getTotal(); // 6counterC.getTotal(): // 6// c:counterA.getTotal(); // 3counterB.getTotal(); // 5counterC.getTotal(): // 6// c:counterA.getTotal(); // 6counterB.getTotal(); // 3counterC.getTotal(): // 1- What does it do in attributes?
- Does not allow to redefine them
- What does it do in methods?
- Does not allow to override them
- What does it do in classes?
- Does not allow to inherit from them
- When we should use it?
- Same reasoning as with the visibility keywords: Guilt presumption.
- Why: Make the next developer think twice before extending from it.
- Key concept: Composition over Inheritance.
- What's the difference?
- Interfaces:
- Doesn't allow to implement method bodies. It only allow us to declare method contracts/headers. <- True until Java8
- They're great because as they have fewer capabilities, they are easier to read and understand without letting us mess up adding behaviour.
- A class can implement different interfaces.
- Abstract classes:
- Allow to implement method bodies.
- A class can only extend from one abstract class.
- Interfaces:
- When we should use
abstractclasses?- Opinion: Almost never. Just exceptional cases. We should have a very big reason to do so 🙂
- When we should use
interfaces?- Opinion: In order to decouple from infrastructure* stuff.
- *Infrastructure: behaviour related to a third party library or component (Postgres DB, AWS SDK, Slack SDK, MailChimp API…)
- Usage example:
interfaceProductRecommender
{
RecommendationsfindFor(ProductIdproductId);
}
finalclassBlueknowProductRecommenderimplementsProductRecommender
{
@OverridepublicRecommendationsfindFor(ProductIdproductId) {
// Call to the Blueknow service API// Parse the JSON response into a `Recommendations` class instancereturnrecommendations;
}
}Example:
- Context:
- We have a Builder system in order to build our applications
- We want to notify the development team once the build is ready to be deployed
- We're testing different messaging apps such as Slack and HipChat
- In order to do not miss our notifications, we want to be notified through the
#dev-notificationsSlack channel, and through thedev-notifications@codely.tvmailing list
- Questions:
- How would you model these different classes and their interactions?
