【问题标题】:Figuring which design pattern to use?确定使用哪种设计模式?
【发布时间】:2017-12-03 19:42:26
【问题描述】:
在大多数无线电设备中,我们可以使用与该类型兼容的解调模式配置我们想要探索和收听电台的波。
至少有两种类型 AM 和 FM。在这种情况下,我们可以将无线电设备建模如下:
class RadioDevice {
void demodulate (String m) {
if(m.equals("FM")
/* FM modelation */
else if(m.equals("AM")
/* AM modelation */
}
}
在这种情况下如何应用策略模式?
【问题讨论】:
标签:
java
design-patterns
software-design
【解决方案1】:
为什么不用多态呢?
制作接口:
interface Radio {
void modulate();
}
然后实现 2 个类:
FMRadio implements Radio{
public void demodule(){
//FM modulation
}
}
AMRadio implements Radio{
public void demodule(){
//AM modulation
}
}
然后,在你的主要,你可以去:
Radio myRadio = new FMRadio();
myRadio.demodule();
【解决方案2】:
如果您可以拥有一个涵盖 AM 和 FM 解调合同的接口,则可以使用策略模式:
Demodulator d; // interface Demodulator { byte[] demodulate(); }
switch(m) {
case "AM":
d = new AMDemodulator();
break;
case "FM"
d = new FMDemodulator();
break;
default:
throw new IllegalArgumentException("Unsupported type '"+ m + "'"); // you could use an Enum instead of a String
}
d.demodulate(waves);
这使您可以即时切换Demodulator 部分,同时保持程序逻辑的其余部分通用(无重复)。
查看此 repo(不是我的)以获取设计模式和示例:https://github.com/iluwatar/java-design-patterns
【解决方案3】:
为了使其成为正确的策略模式,我将在@Ladislav_M 的先前答案中添加使用Context 类,它将包装和封装执行特定策略并为代码提供更大的灵活性:
class Context {
private Radio radio;
public Context(Radio radio) {
this.radio = radio;
}
public Object runStrategy() {
radio.demodulate();
// do any other stuff you want
return ...
}
}
main 中的执行会更方便:
Context context = new Context(new FmRadio());
Object result = context.runStrategy();
或者你可以内联上面的:
Object result = (new Context(new FmRadio())).runStrategy();
当然,您可以在switch 块中选择Radio 的实现,并将其作为变量传递给Context 的构造函数。
【解决方案4】:
这不是策略设计模式的好用例,它是简单的继承用例。使用策略对象的状态不会改变,但不同的算法在不同的时间应用。例如针对员工不同角色(例如临时、永久等)的薪酬包计算。这里的重点是临时员工可以在一天成为永久员工。
在上述情况下,AM 在其生命周期内永远不会成为 FM。因此策略不是它的正确模式。这些(可能)具有共同行为(如果存在)的不同类可以转移到基类。如果他们显示与客户的共同合同,那么即使界面也会完成任务。