钟表

喜欢 以前的 在本文中,让我们讨论一个设计问题来理解命令模式。假设你正在建造一个家庭自动化系统。有一个可编程的遥控器,可以用来打开和关闭家中的各种物品,比如灯、立体声、空调等。它看起来像这样。

null

你可以用简单的if-else语句来实现

if (buttonPressed == button1)
     lights.on()

但我们需要记住,打开一些设备,如立体声,包括许多步骤,如设置cd,音量等。我们还可以重新分配一个按钮来做其他事情。通过使用简单的if-else,我们正在编码实现,而不是接口。此外,还存在紧密耦合。

因此,我们想要实现的是一种提供松散耦合的设计,远程控制不应该有关于特定设备的太多信息。命令模式帮助我们做到这一点。

定义: 这个 命令模式 将一个请求封装为一个对象,从而使我们能够用不同的请求、队列或日志请求参数化其他对象,并支持可撤销的操作。

这个定义一开始有点让人困惑,但让我们来逐步了解一下。与我们上面的问题类似,遥控器是客户端,立体声、灯光等是接收器。在命令模式中,有一个命令对象 封装一个请求 通过将特定接收器上的一组操作绑定在一起。它通过只公开一个方法execute()来实现,该方法会导致在接收器上调用某些操作。

参数化具有不同请求的其他对象 在我们的类比中,用来开灯的按钮以后可以用来打开立体声,或者打开车库门。

排队或记录请求,并支持可撤销的操作 意味着命令的执行操作可以存储状态,以便在命令本身中反转其效果。该命令可能会添加一个unExecute操作,该操作会反转前一次执行调用的效果。它还可以支持记录更改,以便在系统崩溃时重新应用更改。

下面是上述远程控制示例的Java实现:

// A simple Java program to demonstrate
// implementation of Command Pattern using
// a remote control example.
// An interface for command
interface Command
{
public void execute();
}
// Light class and its corresponding command
// classes
class Light
{
public void on()
{
System.out.println( "Light is on" );
}
public void off()
{
System.out.println( "Light is off" );
}
}
class LightOnCommand implements Command
{
Light light;
// The constructor is passed the light it
// is going to control.
public LightOnCommand(Light light)
{
this .light = light;
}
public void execute()
{
light.on();
}
}
class LightOffCommand implements Command
{
Light light;
public LightOffCommand(Light light)
{
this .light = light;
}
public void execute()
{
light.off();
}
}
// Stereo and its command classes
class Stereo
{
public void on()
{
System.out.println( "Stereo is on" );
}
public void off()
{
System.out.println( "Stereo is off" );
}
public void setCD()
{
System.out.println( "Stereo is set " +
"for CD input" );
}
public void setDVD()
{
System.out.println( "Stereo is set" +
" for DVD input" );
}
public void setRadio()
{
System.out.println( "Stereo is set" +
" for Radio" );
}
public void setVolume( int volume)
{
// code to set the volume
System.out.println( "Stereo volume set"
+ " to " + volume);
}
}
class StereoOffCommand implements Command
{
Stereo stereo;
public StereoOffCommand(Stereo stereo)
{
this .stereo = stereo;
}
public void execute()
{
stereo.off();
}
}
class StereoOnWithCDCommand implements Command
{
Stereo stereo;
public StereoOnWithCDCommand(Stereo stereo)
{
this .stereo = stereo;
}
public void execute()
{
stereo.on();
stereo.setCD();
stereo.setVolume( 11 );
}
}
// A Simple remote control with one button
class SimpleRemoteControl
{
Command slot; // only one button
public SimpleRemoteControl()
{
}
public void setCommand(Command command)
{
// set the command the remote will
// execute
slot = command;
}
public void buttonWasPressed()
{
slot.execute();
}
}
// Driver class
class RemoteControlTest
{
public static void main(String[] args)
{
SimpleRemoteControl remote =
new SimpleRemoteControl();
Light light = new Light();
Stereo stereo = new Stereo();
// we can change command dynamically
remote.setCommand( new
LightOnCommand(light));
remote.buttonWasPressed();
remote.setCommand( new
StereoOnWithCDCommand(stereo));
remote.buttonWasPressed();
remote.setCommand( new
StereoOffCommand(stereo));
remote.buttonWasPressed();
}
}


输出:

Light is on
Stereo is on
Stereo is set for CD input
Stereo volume set to 11
Stereo is off

请注意,遥控器不知道如何打开立体声。该信息包含在单独的命令对象中。这减少了它们之间的耦合。

优势:

  • 使我们的代码具有可扩展性,因为我们可以在不更改现有代码的情况下添加新命令。
  • 减少命令的调用方和接收方之间的耦合。

缺点:

  • 增加每个命令的类数

进一步阅读—— Python中的命令方法

参考资料:

如果本文由 苏拉布·库马尔 .如果你喜欢GeekSforgek,并且想贡献自己的力量,你也可以写一篇文章,然后将文章邮寄给评论-team@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。

如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写评论

© 版权声明
THE END
喜欢就支持一下吧
点赞11 分享