我有这些课程:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
private int age;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Admin {
private String name;
private int age;
}
我有一些模板方法模式实现的操作。带算法的基类:
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);
}
两个孩子用实现模板方法:
@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());
}
}
我的问题:
模板方法是避免重复的好方法。但是,如果它将我与继承联系在一起,还有哪些方法可以避免代码重复?在我的例子中,我如何使用合成? (用其他东西替换模板方法?)
您可以使用代理来代替模板模式:
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);
}
}
请注意,这将允许您创建类Operation
和接口。
UPDATE
另一种可能性是定义操作序列和打印操作(甚至更多代码):
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);
}
}
您现在可以使用以下代码:
Operation<MyClass> print = new PrintOperation<>();
Operation<MyClass> seq = new OperationSequence<>(
print, (t) -> {doSomethingWith(t);}, print);
1)如何重写此代码以使用合成?
Strategy Pattern是单向的。实质上,您可以通过将操作传递给数据而不是将数据传递到操作中来反转数据和操作之间的关系。这是一个根本性的变化,因为使用“真实”对象(具有状态和行为)而不是数据类。
2)我是否理解正确使用模板方法时,我附加到继承?
是的,模板方法模式基本上是基于继承。