在这种情况下,星际迷航:TNG 的复制器一直处于故障状态,Guinan 要求我修复它。因为复制器在有人告诉它之前不知道要制作什么饮料,所以我们决定使用抽象工厂模式来创建饮料
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
{
}
然后我们决定将 Data 重新编程为一个郁郁葱葱的
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.Whiskey.DrinkingMethod()
被忽略,但是当我创建命名实例并对其进行测试时,它可以工作?