策略模式定义了一系列算法,封装了它们中的每一个,并确保它们是可互换的。它允许算法独立于客户端的使用而进行修改(这个定义取自 Eric Freeman 和 Elizabeth Robson 所著的《Head First. Design Patterns》一书)。这个定义看起来有点混乱,所以我们需要用普通语言更详细地解释这个定义。让我们从宗教开始:)世界上有许多宗教(忏悔、运动、信仰等)。我们如何用代码来描述这一点。嗯,例如,我们可以选择宗教类并从中继承其他宗教。让我们抽象掉不必要的东西并在 Religion 类中使用一个 believe() 方法。
public abstract class Religion {
public void believe() {
System.out.println("Я верю в Бога-творца этого мира");
}
}
所有其他宗教都可以从这个阶级继承。如果我们只局限于基督教,甚至伊斯兰教和犹太教,那么就不会有问题。
public class Judaism extends Religion {
}
public class Islam extends Religion {
}
public class Christianity extends Religion {
}
但如果你想想现在存在的其他宗教(或以前存在但消失了),那么问题就会出现,至少对于佛教徒来说是这样。你必须重写他们的 believe 方法。
public class Buddhism extends Religion {
@Override
public void believe() {
System.out.println("Есть Бог or боги or нет, это не важно, главное достичь нирваны :)");
};
}
由于有很多宗教,他们甚至相信面食怪物(Pastafarianism),那么在所有这些宗教中你将不得不重新定义信仰方法。但是我们是否可以采取不同的做法,将此方法移至 Faith 接口并在其中实现 believe 方法,并在每个类中实现此方法(并根据我们的意愿在每个类中实现它)?但随后我们就会出现代码重复,至少在犹太人和基督徒中是这样。真主的穆斯林可以用阿拉伯语书写。
public interface Faith {
public void believe();
}
public class Christianity implements Faith {
@Override
public void believe() {
System.out.println("Я верю в Бога-творца этого мира");
}
}
public class Judaism implements Faith {
@Override
public void believe() {
System.out.println("Я верю в Бога-творца этого мира");
}
}
实现默认方法在这里没有多大帮助;宗教如此之多,即使您在 Faith 接口中默认定义了此方法,您也必须在所有非一神教宗教中以自己的方式实现此方法,并重复它某处。 在这种情况下,策略模式为我们提供了什么: 它为当前接口创建现成的模板类,然后将其替换为特定宗教的构造函数。那些。定义并创建与定义开头提到的同一系列算法。
public interface Faith {
public void believe();
}
public class AbrahamicReligion implements Faith {
@Override
public void believe() {
System.out.println("Я верю в Бога-творца этого мира");
}
}
public class BuddismReligion implements Faith {
@Override
public void believe() {
System.out.println("Есть Бог or боги or нет, это не важно, главное достичь нирваны :)");
}
}
public class JediismReligion implements Faith {
@Override
public void believe() {
System.out.println("Да пребудет с вами Сила!");
}
}
并在构造函数中的每个类中替换它们。
public abstract class Religion {
Faith faith;
}
public class Judaism extends Religion{
public Judaism() {
this.faith = new AbrahamicReligion();
}
}
public class Christianity extends Religion{
public Christianity() {
this.faith = new AbrahamicReligion();
}
}
public class Buddhism extends Religion {
public Buddhism() {
this.faith = new BuddismReligion();
}
}
因此,如果您需要在项目中包含另一种宗教,则不必为所有类或部分类重新定义 believe 方法。您只需要实现实现 Faith 接口的缺失类(如果还没有),并将此类添加到新宗教的构造函数中。
public class PastafarianismReligion implements Faith{
@Override
public void believe() {
System.out.println("Кто съел мои макароны???");
}
}
public class Pastafarianism extends Religion {
public Pastafarianism() {
this.faith = new PastafarianismReligion();
}
}
GO TO FULL VERSION