在这种情况下,“星际迷航:TNG”的复制者一直在使用fritz而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
{
}
然后我们决定将数据重新编程为郁郁葱葱的
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()
的第二次调用,但是当我创建命名实例并对其进行测试时,它是否有效?
答案 0 :(得分:1)
你的问题在这里:
//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.Whiskey = data.BoozeFactory.CreateWhiskey();
或者,更好的是,让饮酒者有一种方法可以做到这一点。