-
Notifications
You must be signed in to change notification settings - Fork 0
Contract
#Contract
Every subcomponent contains a Contract interface that binds the different elements together through expectations. The Contract contains different sub-interfaces that pertain to the different core Privvy pieces, eg. View, Presenter, Interactor, Router. The purpose of this interface is to ensure that nothing is coupled with anything else, so that a View should not have to know about the exact Presenter implementation to which it plans to interact with, and so on. Thus, every element holds a reference to an interface of the Contract instead of the actual implementation. This also allows for generification of the elements and methods, and easier testing through dependency injection.
Naturally, the Contract and its children interfaces will not hold every method that each class has -- classes are allowed to have their own private methods. So what methods make it into a Contract? How do we know to escalate a method? To deescalate? We have 2 good rules of thumb:
-
The Privvy component would break without this method. Yes, if one were to take out a very computationally important private method the code would have bugs in it, but the Privvy component could still flow from piece to piece. Exceptions or any other kind of business logic issue isn't the same as the architecture breaking down. Which leads to:
-
Most likely, a Contract method will call another Contract method. This is really the logical extension of point 1. Contract methods are the links in the chain, so it's only natural for them to be connected to each other. If you find that a non-Contract method is calling a Contract method, perhaps the Contract should be modified to either include the current method, or the programmer should delete the current method. The latter is preferable, as bloating the Contract renders the Contract meaningless. Most likely, the logic can be refactored in such a way that helper methods do not interrupt or pollute the chain.
A skeleton Contract looks like this:
//Contract.class is the base Contract for all Privvy subcomponents
interface SkeletonContract extends Contract {
interface View extends Contract.View {
//View methods
//eg. void displayNumber(NumberViewModel number);
}
//Presenters need to hold a reference to a generic View, so this parent needs to be typed
interface Presenter extends Contract.Presenter<View> {
//Presenter methods
}
interface Interactor extends Contract.Interactor {
//Interactor methods
}
interface Router extends Contract.Router {
//Router methods
}
}