/*******************************************************************************
* Companion code for the book "Introduction to Software Design with Java",
* 2nd edition by Martin P. Robillard.
*
* Copyright (C) 2022 by Martin P. Robillard
*
* This code is licensed under a Creative Commons
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
*
* See http://creativecommons.org/licenses/by-nc-nd/4.0/
*
*******************************************************************************/
package e2.chapter7;
public class AbstractDecorator implements CardSource {
final CardSource aElement;
AbstractDecorator( CardSource pElement ) {
aElement = pElement;
}
@Override
public Card draw() {
return aElement.draw();
}
@Override
public boolean isEmpty() {
return aElement.isEmpty();
}
}
Declaring the constructor of an abstract class to be protected is the logical choice, because it can only be called via subclasses.
Declaring the constructor of an abstract class to be protected is the logical choice, because it can only be called via subclasses.
The field holding the decorated element is private
,
which will force the concrete decorators to implement
the decoration strictly in terms of addition to the behavior
available through the interface method. When possible,
this constraint promotes very high encapsulation and
a clear design.
Chapter 7, insight #4
Even in the presence of inheritance, consider keeping your field declarations private to the extent possible, as this ensures tighter encapsulation
The field holding the decorated element is private
,
which will force the concrete decorators to implement
the decoration strictly in terms of addition to the behavior
available through the interface method. When possible,
this constraint promotes very high encapsulation and
a clear design.
Chapter 7, insight #4
Even in the presence of inheritance, consider keeping your field declarations private to the extent possible, as this ensures tighter encapsulation
An abstract class does not have to implement all the required interface methods, and (for that reason) cannot be instantiated. It's mainly intended to serve as an incomplete holder of reusable class member declarations. In this context the class could technically be non-abstract. However, it would be useless. To prevent this alternative, I prefer to declare the class abstract and thus make my intent clear that it's intended to be subclassed.
Chapter 7, insight #12
If some of the fields and methods that can be isolated through inheritance do not add up to a data structure that it makes sense to instantiate, encapsulate them in an abstract class
An abstract class does not have to implement all the required interface methods, and (for that reason) cannot be instantiated. It's mainly intended to serve as an incomplete holder of reusable class member declarations. In this context the class could technically be non-abstract. However, it would be useless. To prevent this alternative, I prefer to declare the class abstract and thus make my intent clear that it's intended to be subclassed.
Chapter 7, insight #12
If some of the fields and methods that can be isolated through inheritance do not add up to a data structure that it makes sense to instantiate, encapsulate them in an abstract class