0

在这种情况下,星际迷航: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()被忽略,但是当我创建命名实例并对其进行测试时,它可以工作?

4

1 回答 1

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();

或者,更好的是,让饮酒者有一种方法可以做到这一点。

于 2013-07-09T20:23:53.433 回答