C# 抽象工厂法;更改传递给对象的工厂
在这个场景中,《星际迷航:TNG》的复制器出了问题,Guinan让我修复它。因为在有人告诉复制器之前,复制器不知道要做什么饮料,所以我们决定使用抽象工厂模式来创建饮料C# 抽象工厂法;更改传递给对象的工厂,c#,visual-studio-2010,design-patterns,C#,Visual Studio 2010,Design Patterns,在这个场景中,《星际迷航:TNG》的复制器出了问题,Guinan让我修复它。因为在有人告诉复制器之前,复制器不知道要做什么饮料,所以我们决定使用抽象工厂模式来创建饮料 public abstract class BoozeFactory { //create abstract methods public abstract Whiskey CreateWhiskey(); public abstract Rum CreateRum();
public abstract class BoozeFactory
{
//create abstract methods
public abstract Whiskey CreateWhiskey();
public abstract Rum CreateRum();
}
public class BlantonsFactory : BoozeFactory
{
public override Whiskey CreateWhiskey()
{
return new BlantonsWhiskey();
}
public override Rum CreateRum()
{
return new BlantonsRum();
}
}
public class VobFactory : BoozeFactory
{
public override Whiskey CreateWhiskey()
{
return new VobWhiskey();
}
public override Rum CreateRum()
{
return new VobRum();
}
}
然后,我们深入研究了复制者可以吐出的品牌
public abstract class Whiskey
{
public int Proof { get; set; }
public abstract void DrinkingMethod();
}
public abstract class Rum
{
public int Proof { get; set; }
public string Name { get; set; }
}
class BlantonsWhiskey : Whiskey
{
public override void DrinkingMethod()
{
Console.WriteLine("This is {0}, you should sip it",GetType().Name);
}
}
class VobWhiskey : Whiskey
{
public override void DrinkingMethod()
{
Console.WriteLine("This is {0}, you should shoot it",GetType().Name);
}
}
class BlantonsRum : Rum
{
}
class VobRum : Rum
{
}
然后我们决定对数据进行重新编程,使其成为一个丰富的数据库
class Drinker
{
public BoozeFactory BoozeFactory { get; set; }
public Whiskey Whiskey { get; set; }
public Rum Rum { get; set; }
public Drinker(BoozeFactory b)
{
//BoozeFactory is abstract and we will have to pass either a Blantons
//or Vob factory to the constructor. This way, the Whiskey and Rum
//properties can depend on what is passed to the constructor at runtime
BoozeFactory = b;
Whiskey = BoozeFactory.CreateWhiskey();
Rum = BoozeFactory.CreateRum();
}
}
这是我们测试的结果
Drinker data = new Drinker(new BlantonsFactory());
data.Whiskey.DrinkingMethod();
//woot, output is correct
//the DrinkingMethod in the VobFactory class gives us different output
data.BoozeFactory = new VobFactory(); //this is what's causing problems
data.BoozeFactory.CreateWhiskey();
data.Whiskey.DrinkingMethod();
//even though the BoozeFactory property of data has been changed
//the output hasn't changed
BoozeFactory b = new VobFactory();
data.Whiskey = b.CreateWhiskey();
data.Whiskey.DrinkingMethod();
//now the output is correct
为什么除非实例化BoozeFactory的新命名实例,否则对data.wisky.DrinkingMethod()
的第二次调用将被忽略,但当我创建命名实例并对其进行测试时,它会起作用?您的问题在于:
//the DrinkingMethod in the VobFactory class gives us different output
data.BoozeFactory = new VobFactory(); //this is what's causing problems
data.BoozeFactory.CreateWhiskey();
data.Whiskey.DrinkingMethod();
您从不将新威士忌分配给数据。威士忌属性,您创建它,然后立即丢弃它。你应该这样写你的第二行:
data.Whiskey = data.BoozeFactory.CreateWhiskey();
或者,更好的是,让饮酒者有一个方法来实现这一点。测试结果的3行输出究竟是什么?对data.whisky.DrinkingMethod()的第一个调用是
Console.WriteLine(“这是{0},您应该sip它”,GetType().Name)第二个调用应该是Console.WriteLine(“这是{0},你应该拍摄它”,GetType().Name)
这是因为来自抽象类的重写DrinkingMethodWhisky
我知道应该调用什么,如果我不理解继承和抽象,我不会尝试回答这个问题。我想问的是,控制台的输出是什么,一行接一行?i、 e.这是VobWhiskey,你应该啜一口(\n)这是VobWhiskey,你应该啜一口(\n)这是布兰顿威士忌,你应该开枪第一个电话是“这是布兰顿威士忌,你应该啜一口”,第二个电话是“这是VobWhiskey,你应该开枪”。