Template method and inheritance or composition - java

I have these classes:
#Data
#AllArgsConstructor
#NoArgsConstructor
public class User {
private String name;
private int age;
}
#Data
#AllArgsConstructor
#NoArgsConstructor
public class Admin {
private String name;
private int age;
}
And I have some operations with template method pattern implementation. Base class with algorithm:
public abstract class Operation<T> {
public void process(T t) {
System.out.println(t);
updateName(t);
System.out.println(t);
}
protected abstract void updateName(T t);
}
Two children with implementation template method:
#Component
public class UserOperation extends Operation<User> {
#Override
protected void updateName(User user) {
String newName = user.getName().toUpperCase();
user.setName(newName);
}
}
#Component
public class AdminOperation extends Operation<Admin> {
#Override
protected void updateName(Admin admin) {
String name = admin.getName();
StringBuilder builder = new StringBuilder();
builder.append(name);
StringBuilder reverse = builder.reverse();
admin.setName(reverse.toString());
}
}
My questions:
How do I rewrite this code to use composition?
Do I understand correctly that when using the template method, I attach to inheritance?
The template method is a great way to avoid duplication. But if it binds me to inheritance, what other ways are there to avoid code duplication? In my example, how can I use composition? (replace the template method with something else?)

1) How do I rewrite this code to use the composition?
The Strategy Pattern is one way. Essentially, you would reverse the relationship between data and operations by passing the operations into the data rather than passing the data into the operations. This is a fundamental change, because "real" objects (with state and behavior) are used instead of data classes.
2) Do I understand correctly that when using the template method, I attach to inheritance?
Yes, the Template Method Pattern is fundamentally based on inheritance.

Instead of template pattern you could have a proxy:
public abstract class Operation<T> {
public abstract void updateName(T t);
}
public class OperationProxy<T> extends Operation<T> {
private final Operation<T> delegate;
public OperationProxy(Operation<T> delegate) {
this.delegate = delegate;
}
#Override
public void updateName(T t){
System.out.println(t);
delegate.updateName(t);
System.out.println(t);
}
}
Note that this would allow you to make class Operation and interface.
UPDATE
Another possibility is defining sequences of operations, and a print operation (even more code):
public interface Operation<T> {
void updateName(T t);
}
public class OperationSequence<T> implements Operation<T> {
private final Operation<T>[] steps;
public OperationSequence(Operation<T>... steps) {
this.steps = steps;
}
#Override
public void updateName(T t){
for (Operation<T> step: steps) {
step.updateName(t);
}
}
}
public class PrintOperation<T> implements Operation<T> {
#Override
public void updateName(T t){
System.out.println(t);
}
}
You can now use the following code:
Operation<MyClass> print = new PrintOperation<>();
Operation<MyClass> seq = new OperationSequence<>(
print, (t) -> {doSomethingWith(t);}, print);

Related

Java, Inheritance, Generics - using parameters of subtypes in template method implementations

I am building an application that is generating PDF documents for sales orders and sales invoices. For simplicity I have exluded redundant logic and fields.
Here is my class structure:
public class SalesEntity {
public String name;
public String createdDate;
}
public class SalesOrder extends SalesEntity {
}
public class SalesInvoice extends SalesEntity {
public String invoiceSpecificField;
}
and similar scturcure for wrapper and list items:
public class SalesEntityItem {
public String name;
public String price;
}
public class SalesOrderItem extends SalesEntityItem {
}
public class SalesInvoiceItem extends SalesEntityItem {
public String invoiceItemSpecificField;
}
public class SalesEntityResponse {
public SalesEntity salesEntity;
public List<SalesEntityItem> salesEntityItems;
}
and here is first part of the problem.
public class SalesOrderEntityResponse extends SalesEntityResponse {
// public SalesOrder salesEntity; <-- say somehow to java that in this subclass the property type should also be subclass
// public List<SalesOrderItem> salesEntityItems;
}
For building mechanism I am using template method:
public class PDFBuilder extends AbstractPDFBuilder {
protected void buildPdfDocument(Map<String, Object> model /*...*/) throws Exception {
/*...*/
addEntityNumber(document, salesEntityResponse);
addItems(document, salesEntityResponse);
}
}
public class OrderPDFBuilder extends PDFBuilder {
/*...*/
#Override
protected void addEntityNumber(Document document, SalesEntityResponse entityResponse) throws DocumentException {
/*...*/
PdfPTable documentNameTable = new PdfPTable(1);
Phrase documentNamePhrase = new Phrase(entityResponse.labels.account_number, timesFont);
PdfPCell documentNameCell = new PdfPCell(documentNamePhrase);
documentNameTable.addCell(documentNameCell);
document.add(documentNameTable);
}
#Override
protected void addItems(Document document, SalesEntityResponse entityResponse) throws DocumentException {
/*...*/
for (SalesEntityItem salesEntityItem : entityResponse.salesEntityItems) {
/* Items adding specific logic */
}
}
}
And if first part of somwhow solveable, here comes main part:
Question: How can I make specific template method implementations (OrderPDFBuilder, InvoicePDFBuilder)
receive parameters of subtype SalesEntityResponse (SalesOrderResponse and SalesInvoiceResponse) respectively? So that in specific implementations I can use specific fields of those entities. Does it make sense? I assume here is something related to bounded types, but I am not sure how to use it properly.
As you've established generics are how you achieve this. So firstly you'll need to stick your generics decleration on the SalesEntityResponse:
public class SalesEntityResponse<T extends SalesEntity, U extends SalesEntityItem> {
public T salesEntity;
public List<U> salesEntityItems;
}
Then in the declaration of your subtypes you tell it what concrete types they hold:
public class SalesOrderEntityResponse extends SalesEntityResponse<SalesOrder, SalesOrderItem> {
}
To make the "magic" work in your addItems method you'll have to also have to add generics to which ever class/interface declares the addItems method, this is presumably AbstractPDFBuilder? So something like:
public abstract class AbstractPDFBuilder<T extends SalesEntity, U extends SalesEntityItem, V extends SalesEntityResponse<T, U>> {
protected abstract void addItems(Document document, V entityResponse) throws DocumentException;
}
}
And then your concrete PDFBuilder types need to supply the relavant generics:
public class SalesOrderPDFBuilder extends AbstractPDFBuilder<SalesOrder, SalesOrderItem, SalesOrderEntityResponse> {
protected void addItems(Document document, SalesOrderEntityResponse entityResponse) {
}
}

java mutant design pattern and compiler error 'Interface' cannot be inherited with different type arguments 'TypeA' and 'TypeB'

I am way over thinking this: What I am trying to do is [hopefully not reinvent the wheel and] come up w/ a [Android] Java eventing mechanism that allows subclasses to pre-define an arbitrary set of "features" with getters and setters that fire individual callbacks.
I think I am fusioning some combination of Command, Visitor, Decorator, Facade and Observer patterns here, and confusing myself along the way.
I have been programming for well over 20 years, but I feel like a n00b on this fairly simple problem! :(
I have searched SO for the compiler error and read many of the results, but I still haven't found a solution that works for me.
(How to make a Java class that implements one interface with two generic types? seems to be the most relevant one that I have found, but I also want to generically get the values and fire events to callbacks when they are set).
First, let the below mostly valid code speak for itself...
interface IFeature
{
}
interface IFeatureCallbacks<T extends IFeature>
{
boolean onChanged(Feature<T> c);
}
public static class Feature<T extends IFeature>
{
private Set<IFeatureCallbacks<T>> listeners = new LinkedHashSet<>();
public void addListener(IFeatureCallbacks<T> listener)
{
listeners.add(listener);
}
public void removeListener(IFeatureCallbacks<T> listener)
{
listeners.remove(listener);
}
protected void onChanged()
{
for (IFeatureCallbacks<T> listener : listeners)
{
listener.onChanged(this);
}
}
}
//
interface IFeatureA
extends IFeature
{
int getA();
}
interface IFeatureACallbacks
extends IFeatureCallbacks<IFeatureA>
{
}
public static class FeatureA
extends Feature<IFeatureA>
implements IFeatureA
{
private int a;
public void setA(int value)
{
a = value;
onChanged();
}
#Override
public int getA()
{
return a;
}
}
//
interface IFeatureB
extends IFeature
{
boolean getB();
}
interface IFeatureBCallbacks
extends IFeatureCallbacks<IFeatureB>
{
}
public static class FeatureB
extends Feature<IFeatureB>
implements IFeatureB
{
private boolean b;
public void setB(boolean value)
{
b = value;
onChanged();
}
#Override
public boolean getB()
{
return b;
}
}
//
interface IDeviceWithFeatureA
extends IFeatureA
{
}
interface IDeviceWithFeatureACallbacks
extends IFeatureACallbacks
{
}
public static class DeviceWithFeatureA
extends Feature<IDeviceWithFeatureA>
implements IDeviceWithFeatureA
{
FeatureA a = new FeatureA();
public void addListener(IDeviceWithFeatureACallbacks listener)
{
a.addListener(listener);
}
public void setA(int value)
{
a.setA(value);
}
#Override
public int getA()
{
return a.getA();
}
}
//
interface IDeviceWithFeatureB
extends IFeatureB
{
}
interface IDeviceWithFeatureBCallbacks
extends IFeatureBCallbacks
{
}
public static class DeviceWithFeatureAB
extends Feature<IDeviceWithFeatureB>
implements IDeviceWithFeatureB
{
FeatureB b = new FeatureB();
public void addListener(IDeviceWithFeatureBCallbacks listener)
{
b.addListener(listener);
}
public void setB(boolean value)
{
b.setB(value);
}
#Override
public boolean getB()
{
return b.getB();
}
}
The above code seems to work fine, albeit something about it smells a bit off.
The problem is when I try to do this:
interface IDeviceWithFeatureAAndFeatureB
extends IFeatureA, IFeatureB
{
}
/*
Compiler error:
'IFeatureCallbacks' cannot be inherited with different type arguments 'IFeatureA' and 'IFeatureB'
*/
interface IDeviceWithFeatureAAndFeatureBCallbacks
extends IFeatureACallbacks, IFeatureBCallbacks
{
}
public static class DeviceWithFeatureAB
extends Feature<IDeviceWithFeatureAAndFeatureB>
implements IDeviceWithFeatureAAndFeatureB
{
FeatureA a = new FeatureA();
FeatureB b = new FeatureB();
public void addListener(IDeviceWithFeatureAAndFeatureBCallbacks listener)
{
a.addListener(listener);
b.addListener(listener);
}
public void setA(int value)
{
a.setA(value);
}
#Override
public int getA()
{
return a.getA();
}
public void setB(boolean value)
{
b.setB(value);
}
#Override
public boolean getB()
{
return b.getB();
}
}
I am less interested in trying to figure out how to make what I am trying to do compilable, and I am more interested in what about my abuse of a pattern is way off base so that I can re-write it to be both simpler and compile.
You are abusing the basic "pattern" of OOP -- inheritance. The adage is that "favor composition over inheritance". Think in terms of "contains", instead of "is-a".
Take Zoo for example. A zoo is just a bunch of animals, right? So naturally, we may want to declare Zoo as subtype of Set<Animal>. Perhaps even have class Zoo extends HashSet<Animal>.
However, that is likely a wrong design. A zoo is actually a lot of things. It contains a set of animals, sure; but it also contains a set of people (as workers, not exhibits (although...) ). So it's better to
class Zoo
Set<Animal> animals(){ ... }
Set<Person> workers(){ ... }
Anywhere we need to treat a zoo as a set of animals, just use zoo.animals(); think of it as a type cast, or projection. We don't need inheritance here.
In your design, you have too many types; what's worse, too many type relationships. It seems that you simply need one generic class that reads/writes value of T, and contains listeners of T
class Feature<T>
T value;
// getter
// setter
Set<ChangeListener<T>> listeners;
interface ChangeListener<T>
void onChange(T oldValue, T newValue)
A device contains a bunch of features
class SomeDevice
Feature<Integer> featureA = new Feature<>();
Feature<Boolean> featureB = new Feature<>();
That's it. You can operate on feature A of the device by operating on itsfeatureA.

Building fluent APIs in Java to build testdata for database

Im trying to make a small DSL in Java that I can use to populate testdata in a database. The language I would like to use is as follows.
createRowInTableA().
createRowInTableB().
createRowInTableA().
createRowInTableB().
createRowInTableC().
end();
The order the tables are created is important, for example tableB depends on tableA and tableC depends on tableA and tableB. Therefore I want to make it so that the option to create tableB only is available directly after tableA is created etc. I have started to create the interfaces describing the DSL but I don't know how I should actually implement the interfaces inorder to make the type of nested behavior I'm looking for. This is what the interfaces looks like.
public interface End {
public void sendTestData();
}
public interface TableA extends End {
public Builder createRowInTableA();
}
public interface TableB extends TableA {
public Builder createRowInTableB();
}
public interface TableC extends TableB {
public Builder createRowInTableC();
}
However when I start implementing this language using builder pattern to create a fluent API the hierarchy I want goes away.
public class DBBuilder implements TableC {
static class Builder {
public Builder createRowInTableA(){...}
public Builder createRowInTableB(){...}
public Builder createRowInTableC(){...}
}
}
You can use a set of interfaces and class adapters:
public interface canCreateTableAIf{
public DBBuilderB createRowInTableA()
}
public interface canCreateTableBIf{
public DBBuilderC createRowInTableB()
}
public interface canCreateTableCIf{
public DBBuilderD createRowInTableC()
}
public class canCreateTableA implements canCreateTableAIf (){
public DBBuilderB createRowInTableA(){
...
}
}
public class canCreateTableB implements canCreateTableBIf (){
public DBBuilderC createRowInTableB(){
...
}
}
public class DBBuilderRoot extends canCreateTableA {
}
public class DBBuilderB extends canCreateTableB {
}
public class DBBuilderBCD extends canCreateTableB,canCreateTablec,canCreateTableD {
}
This is not so complicated. But I would check if there is a better way than using fluent Builders. Java 8 for example offers closures. Hier is my suggestion. I've not compiled and tested it. The idea should work but there might be syntax errors.
public class ABuilder
{
private BBuilder subBuilder;
public ABuilder()
{
subBuilder = new BBuilder(this);
}
public BBuilder createRowForA()
{
// your code
return this.subBuilder;
}
public void end()
{
// send test data
}
}
x
public class BBuilder
{
private ABuilder parentBuilder;
private CBuilder subBuilder;
public BBuilder( ABuilder parentBuilder )
{
this.parentBuilder = parentBuilder;
this.subBuilder = new CBuilder(this);
}
public CBuilder createRowForB()
{
// your code
return this.subBuilder;
}
public ABuilder end()
{
return this.parentBuilder;
}
}
x
public class CBuilder
{
private BBuilder parentBuilder;
public CBuilder( BBuilder parentBuilder )
{
this.parentBuilder = parentBuilder;
}
public CBuilder createRowForC()
{
// your code
// I Assume you want to be able to write more than 1 C-row
return this;
}
public BBuilder end()
{
return this.parentBuilder;
}
}
Then you can do:
(new ABuilder())
.createRowForA()
.createRowForB()
.createRowForC()
.end()
.end()
.end();
(new ABuilder())
.createRowForA()
.createRowForB()
.end()
.createRowForB()
.createRowForC()
.end()
.end()
.end();
I'm sure you see more exmples. ;-)

Generic Builder in Java

I created a builder for a lookup table and using it as shown below.
public class RaceCodeDataBuilder {
private RaceCode raceCode;
public RaceCodeDataBuilder() {
raceCode = new RaceCode();
}
public RaceCodeDataBuilder code(String code) {
raceCode.setCode(code);
return this;
}
public RaceCodeDataBuilder displayName(String displayName) {
raceCode.setDisplayName(displayName);
return this;
}
public RaceCode build() {
return raceCode;
}
}
Using this builder in a test:
RaceCode mockRaceCode = new RaceCodeDataBuilder()
.code("2054-5")
.displayName("Black or African American")
.build();
I am expecting lot more similar builders for other look up tables such as StateCodeBuilder, GenderCodeBuilder and all of them have just "code" and "displayName", similar to above builder.
I want to create a generic builder and avoid creating several builder classes doing the same job with different name.
I attempted something in generics but I am way off..
public class CodeDataBuilder<T>{
private T t;
public CodeDataBuilder(T t) {
this.t = t;
}
public CodeDataBuilder code(String code) {
raceCode.setCode(code); // Cant write T.setCode here for obvious resons
return this;
}
public CodeDataBuilder displayName(String displayName) {
raceCode.setDisplayName(displayName); // Cant write T.setDisplayNamehere for obvious resons
return this;
}
public T build() {
return t;
}
}
Can someone help me with that?
Thank you.
Create an interface BuildableCodeData with the methods you need, and implement it with classes like RaceData.
Your code will then look like:
public interface BuildableCodeData {
public void setCode(String code);
public void setDisplayName(String name);
}
public class Builder<T extends BuildableCodeData> {
private T codeData;
public Builder(T codeData) {
this.codeData = codeData;
}
public Builder<T> setCode(String code) {
codeData.setCode(code);
return this;
}
public Builder<T> setDisplayName(String displayName) {
codeData.setDisplayName(displayName);
return this;
}
public T build() {
return codeData;
}
}
It looks more like you should use an interface, and just make your build method return that interface. For example:
public interface Buildable{
void setDisplayName(String name);
void setCode(String code);
}
public class CodeDataBuilder {
private Buildable mObj;
public CodeDataBuilder(Buildable mObj) {
this.mObj = mObj;
}
public CodeDataBuilder code(String code) {
mObj.setCode(code); // Cant write T.setCode here for obvious resons
return this;
}
public CodeDataBuilder displayName(String displayName) {
mObj.setDisplayName(displayName); // Cant write T.setDisplayNamehere for obvious resons
return this;
}
public Buildable build() {
return mObj;
}
}
}
Then just make any object you want to build implement the Buildable interface.
If you create an interface with the needed methods:
interface CodeModel {
public void setCode(String s);
public void setDisplayName(String s);
}
You can then ask your generic class to accept only T extends CodeModel, like so:
class CodeDataBuilder<T extends CodeModel> {
// T has setCode method now!
}
Hope this helps!
If you have an interface with some standard functions, you can create a generic builder for it. The base builder would be abstract, and for each concrete implementation, there would be a concrete builder.
Interface:
public interface CodeNameable {
String getCode();
String getName();
}
Concrete implementation:
public class CodeNamedCar implements CodeNameable {
private String code;
private String name;
public CodeNamedCar(String code, String name) {
this.code = code;
this.name = name;
}
}
Abstract builder:
public abstract class CodeNameBuilder<C extends CodeNameable> {
public String code;
public String name;
public CodeNameBuilder() {
}
}
Concrete builder:
public abstract class CarBuilder extends CodeNameBuilder<CodeNamedCar> {
public CarBuilder() {
}
public CarBuilder code(String co_de) {
this.code = code;
return this;
}
public CarBuilder name(String name) {
this.name = name;
return this;
}
public CodeNameCar build() {
return (new CodeNameCar(code, name));
}
}
Then you can use it as you hoped:
CodeNamedCar car = new CarBuilder().code("thecode").name("Mazda").build();
Using this design, you'll need to check each field for correctness (non-null and non-empty, for example) in the CodeNameCar constructor. There are other ways to design it, too.
The builder pattern is about to crate a new instance of class and initialize it as much as required to do.
In the way you are going you tend to finish with a partial setter of some properties and create a possible fake relation because two object has the same attributes.
To support this in example everything has an name attribute but you do not create a super interface to called Nameable and implements its in every possible place.
If those attribute are shared across your classes you should think to create a class for them.
class Code {
int number;
String name;
}
class Race {
Code code;
//other attributes;
}
Then you have a one builder for code and another for race.
Note also that the good design is a balance of trade offs. If two fields are common for 5 classes is the a purpose to make the code complex and create a dedicated mechanize that will only pack the initialization and will not do anything productive.

Suitable design using Generics with Wildcard

I am trying to determine if generics would be able to help me with designing a better and scalable solution. In my application, there is a model class which is responsible for loading data from data sources and I use a ModelProxy class to expose some of the methods in the Model class.
public interface ModelProxy {
public int getOrderCount();
public int getCustomerCount();
}
public abstract class AbstractModel {
public abstract ModelProxy loadData(Configuration configuration);
}
public class ConcreteModel extends AbstractModel {
public ModelProxy loadData(Configuration configuration) {
loadInternal();
return new ConcereteModelProxy(this);
}
}
Everything looks good so far, but I am looking to see if generics (with wildcards) can help me design a better solution that would allow to be extend the ModelProxy interface or the Configuration class. For example, in another Concrete Model class I woukd like to use a ExtendedConfiguration class and ExtendedModelProxy.
public ExtendedModelProxy extends ModelProxy {
// Additional methods
public int getTotalCount();
}
public class ConcereteModel2 extends AbstractModel {
public ExtendedModelProxy loadDate(ExtendedConfiguration configuration) {
return new ConcreteExtendedModelProxy(this);
}
}
Will Java Generics help me to achieve something like above?
Or Maybe my design is flawed that I need to re-design it. Any suggestions would be very helpful.
Thanks,
Example Client Code:
public abstract class Service {
public ModelProxy load(Configuration configuration) {
return getModel().loadData(configuration);
}
protected abstract AbstractModel getModel();
}
public class ServiceImpl extends Service {
protected AbstractModel getModel() {
return new ConcreteModel();
}
public static void main() {
Service service = new ServiceImpl();
ModelProxy proxy = service.load(configuration);
System.out.println(proxy.getOrderCount());
}
}
public class ExtendedServiceImpl extends Service {
protected AbstractModel getModel() {
return new ConcreteModel2();
}
public static void main() {
Service service = new ExtendedServiceImpl();
ExtendedModelProxy proxy = (ExtendedModelProxy) service.load(configuration);
System.out.println(proxy.getTotalCount());
}
}
I hope to not have confused with too much. In the ExtendedServiceImpl, you can see I need to cast ModelProxy to ExtendedModelProxy to be able to access the method getTotalCount. My thinking was maybe I can use generics to avoid the casts. Something like
public abstract <M extends ModelProxy, C extends Configuration> M loadData(C configuration);
Maybe I am overcomplicating things and really my current design is all I need. Not sure...
How about this kind of thing
package jj;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.*;
interface Configuration {
}
interface Model {
}
interface OrderModel extends Model {
public int getOrderCount();
public int getCustomerCount();
}
interface CustomerModel extends Model {
public int getName();
public int getAddress();
}
abstract class AbstractModel<M extends Model> {
#SuppressWarnings("unchecked")
public M loadData(Configuration configuration) {
// connect to stuff
Object connection = null;
loadInternal(configuration, connection);
// do some other stuff
return (M) Proxy.newProxyInstance(null, new Class<?>[]{getModelClass()}, null);
}
protected abstract void loadInternal(Configuration configuration,
Object connection);
protected abstract InvocationHandler getInvocationHandler(Object connection);
protected abstract Class<M> getModelClass();
}
class ConcreteOrderModel extends AbstractModel<OrderModel> {
public void loadInternal(Configuration configuration,
Object connection) {
}
protected InvocationHandler getInvocationHandler(Object connection) {
return null;
}
protected Class<OrderModel> getModelClass() {
return OrderModel.class;
}
}
class ConcreteCustomerModel extends AbstractModel<CustomerModel> {
public void loadInternal(Configuration configuration,
Object connection) {
}
protected InvocationHandler getInvocationHandler(Object connection) {
return null;
}
protected Class<CustomerModel> getModelClass() {
return CustomerModel.class;
}
}

Categories