【问题标题】:Strategy pattern used in Factory pattern?工厂模式中使用的策略模式?
【发布时间】:2019-01-25 06:05:51
【问题描述】:

我正在使用工厂模式编写代码。在 switch 情况下,我实际上是在返回 Class 对象。使用这个返回类,我将调用一个方法。这是策略模式的一个例子吗?

using System;
using System.Linq;

namespace ConsoleApplication1
{
    public interface IVehicle
    {
          void Manufacture();
    }

    public class Car : IVehicle
    {
        public void Manufacture()
        {
            Console.WriteLine("Car Manufacturing");
         }
     }

     public class Bike : IVehicle
     {
         public void Manufacture()
         {
            Console.WriteLine("Bike Manufacturing");
         }
     }

     public static class factory
     {
         public static IVehicle GetVehicle(string name)
         {
            switch(name)
            {
                case "Car":
                    return new Car();
                case "Bike":
                    return new Bike();
                default:
                    throw new ArgumentException();
            }
        }
    }

    public class program
    {
        public static void Main()
        {
            Console.WriteLine("Please enter Car or Bike for manufacture");
            var vehicleName = Console.ReadLine();
            factory.GetVehicle(vehicleName).Manufacture();
            Console.ReadLine();
        }
    }

}

你能解开我的误解吗?这段代码是工厂模式和策略模式的例子吗? 提前谢谢你。

编辑

这是策略模式的一个例子吗?我刚刚编辑了 Program.cs

public class program
{
    public static void Main()
    {
        Console.WriteLine("Please enter Car or Bike for manufacture");
        var vehicleName = Console.ReadLine();
        var vehicle = factory.GetVehicle(vehicleName);


    }

    public void manufacture(IVehicle vehicle)
    {
        // assume that this method is in different class and method is calling with strategy as i understood.
        vehicle.Manufacture();
    }
}

【问题讨论】:

  • 这可能更适合Software Engineering。我不相信这是策略模式的一个例子,因为没有使用策略接口。工厂类中的所有内容都是硬编码的。
  • 您在此处实现的是 Factory Pattern 的简单示例,而不是 Strategy Pattern 的示例,John 在上面评论。为了更好地理解,请查看Strategy Pattern vs Factory pattern。
  • 谢谢@John 和 vikscool。如果您能清除我的疑问,我已经编辑了问题。
  • 即使是制造这也不是战略模式
  • @DarshitGandhi 如果您对我们的答案有不理解的地方,请随时提问

标签: c# design-patterns


【解决方案1】:

您的代码是带有参数的工厂方法的示例。您可以在没有参数的情况下执行工厂方法,这是更好的做法。

策略模式编辑算法,我喜欢 Abstract class 的策略,而不是 Interface。

例如,您的策略可能如下所示:

首先,Strategy 类。例如计算油耗:

public abstract class Strategy
{
    public abstract int FuelConsumption(int km);
}

现在,您可以使用strategies。我会做其中两个,快速驾驶和慢速驾驶:

public class FastDriving : Strategy
{
    //you need to override abstract methods from abstract class that
    // are mentioned in Strategy as acstract, or any else abstract class
    public override double FuelComsumption(int km) => km * fuelPer100Km;

    private int fuelPer100Km = 30;
}

public class SlowDriving : Strategy
{
    //same history as above
    public override double FuelComsumption(int km) => km * fuelPer100Km - 100;

    private int fuelPer100Km = 10;
    //u need to edit alghoritm to strategy be a strategy
}

现在,您可以在每辆车中为您的Abstract Class Strategy 设置一个属性:

public class Bike : IVehicle
 {
     public void Manufacture()
     {
        Console.WriteLine("Bike Manufacturing");
     }

     int i = 1000; //some propertys needed to calculate alghoritm

     // method in vehicle class that we use to strategy, to edit our alghoritm
     public int CaluculateFuelConsumption() => Strategy.FuelConsumption() - i;

     //here is a property of your strategy
     public Strategy strategy {get; set;};
 }

现在,您需要填充您的策略。如果你愿意,你可以在类正文中或在 main 中进行:

Strategy strategy = new FastDriving();
Strategy strategy = new SlowDriving();

但你可以做得更好。

只做一个抽象类,比如Vehicle:

public abstract class Vehicle 
{
    public Strategy strategy {get; set;};
}

然后,您的车辆可以如下所示:

 public class Bike : Vehicle, IVehicle
 {
      public void Manufacture()
     {
     Console.WriteLine("Bike Manufacturing");
     }

     int i = 1000; //some propertys needed to calculate alghoritm

     // method in vehicle class that we use to strategy, to edit our alghoritm
     public int CaluculateFuelConsumption() => Strategy.FuelConsumption() - i;

     //We deleted Strategy, because abstract Car class have already Strategy
     //We dont need override non abstract method. Only abstract propertys
     //need to be overrided
   }  

现在,在你的主类中,你可以做汽车列表,通过工厂方法填充它并附加Strategy

List<Vehicle> vehicles= new List<Vehicle>();

foreach(Vehicle vehicle in vehicles)
    {
        //its not factory, but you can use factory for your post here
        switch(name)
        {
            case "Car":
                vehicle =  new Car();
            case "Bike":
                vehicle = new Bike();
            default:
                throw new ArgumentException();
        }
        //now, we populate strategy
        vehicle.strategy = new FastDriving():

    }

然后你可以通过一个循环计算所有的油耗:

 foreach(Vehicle vehicle in vehicles)       
        int fuel += vehicle.CalculateFuelConsumption();

策略,我写的是PUSH 策略。还有PULL 策略。你可以在网上阅读。我相信,我的回答足以让你理解,策略是如何运作的:)

如果您想了解更多关于模式的信息,我向您推荐该网站:

Design Patterns

【讨论】:

  • 工厂模式到底在哪里?
  • 工厂模式不是个案。在第一个 foreach 中,他可以使用他的开关来填充 new Bike() 或 new Car() 中的汽车列表,如他所愿。
  • 好的,我编辑了我的答案。如果这对 OP 来说还不够,我将从他的代码中做一个工作示例。我相信他会明白的,如何通过我上面的代码来做到这一点(我编辑了 foreach 我用策略填充汽车)
  • 重点是他在学习,他选择的例子,你更新的不是很好。我宁愿建议让factory 接收例如EnviromentFriendlyComute 和FastComute 策略,然后分别返回自行车或汽车......
  • 好的,在下一次编辑中,我将仔细查看他的原始帖子。对于我的这种回答状态,我相信他会更了解策略。我也提供了我的答案以及策略的工作示例。
【解决方案2】:

我会说是的,GetVehicle 方法是称为simple factory 的专用工厂模式的一个示例,您正在使用它返回的东西以使用策略模式的方式 - 调用代码不知道战略的具体实施。

【讨论】:

    猜你喜欢
    • 2013-04-30
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多