C# C语言中的工厂模式#
我有点能够理解工厂模式,并提出了这个实现C# C语言中的工厂模式#,c#,.net,design-patterns,.net-4.5,C#,.net,Design Patterns,.net 4.5,我有点能够理解工厂模式,并提出了这个实现 class Program { static void Main(string[] args) { Console.WriteLine("Enter the fruit name to get the Fruit!"); string fruit = Console.ReadLine(); FruitsList fruits; if (Enum.TryParse(fruit
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter the fruit name to get the Fruit!");
string fruit = Console.ReadLine();
FruitsList fruits;
if (Enum.TryParse(fruit, true, out fruits))
{
var fruitWeight = GetFruitWeight(fruits);
Console.ReadLine();
}
else
{
Console.WriteLine("Fruit Name is undefined!");
Console.ReadLine();
}
}
private static object GetFruitWeight(FruitsList fruitNumber)
{
switch (fruitNumber)
{
case FruitsList.Banana:
return new Banana();
case FruitsList.Apple:
return new Apple();
}
return null;
}
}
internal class Banana : IFruits
{
public float ReturnFruitWeight()
{
return (float)10.00;
}
}
public interface IFruits
{
float ReturnFruitWeight();
}
public class Apple : IFruits
{
public float ReturnFruitWeight()
{
return (float)30.00;
}
}
public enum FruitsList
{
Apple,
Banana,
}
我的整个想法(从理论上理解)是GetFruitWeights函数应接受枚举类型,然后返回水果权重。我能得到一个特定水果的物体,但现在我想知道如何从水果物体中得到水果的重量
另外,在我的疑问列表中,我在这个实现中是否真的遵循了工厂模式?而且,互联网上的一些材料也使用了抽象类?我应该遵循什么?接口实现,还是应该使用抽象类并重写它
提前感谢您的帮助。如果您不打算在返回水果时使用
水果
对象,那么我将直接返回重量,而不是水果对象。factory方法名称实际上表示它返回的是权重,而不是对象,因此理论上它是正确的方法,即
const float AppleWeight = 10;
const float BananaWeight = 10.4;
...
public static float GetFruitWeight(FruitList fruitType)
{
switch (fruitType)
{
case FruitsList.Apple:
return AppleWeight;
case FruitsList.Banana:
return BananaWeight;
default:
return 0;
}
}
但是,如果您确实打算使用fruit
对象,那么我会将您的方法重命名为GetFruit
,返回IFruits
(不要框),并在fruit
实例上调用ReturnFruitWeight
以获取权重
在这个实现中,我真的遵循了工厂模式吗
factory模式的要点是允许您在不知道具体类型的情况下创建对象,因此,这里是factory方法模式的一个相当基本的示例
互联网上的一些材料也使用抽象类?我应该遵循什么?接口实现,还是应该使用抽象类并重写它
这完全取决于您的应用程序设计。例如,我个人只会在以下情况下引入抽象基类:
- 我可以在各个类之间共享一些通用代码
- 我需要某种方法来确定某个特定的类属于某个特定类型的族,即
是香蕉
的一种类型水果
除此之外,我可能几乎总是选择接口类型方法。请记住,两者都可以,没有理由不能有一个支持特定接口的抽象基类…如果在返回时不打算使用
fruit
对象,那么我将直接返回权重而不是fruit对象。factory方法名称实际上表示它返回的是权重,而不是对象,因此理论上它是正确的方法,即
const float AppleWeight = 10;
const float BananaWeight = 10.4;
...
public static float GetFruitWeight(FruitList fruitType)
{
switch (fruitType)
{
case FruitsList.Apple:
return AppleWeight;
case FruitsList.Banana:
return BananaWeight;
default:
return 0;
}
}
但是,如果您确实打算使用fruit
对象,那么我会将您的方法重命名为GetFruit
,返回IFruits
(不要框),并在fruit
实例上调用ReturnFruitWeight
以获取权重
在这个实现中,我真的遵循了工厂模式吗
factory模式的要点是允许您在不知道具体类型的情况下创建对象,因此,这里是factory方法模式的一个相当基本的示例
互联网上的一些材料也使用抽象类?我应该遵循什么?接口实现,还是应该使用抽象类并重写它
这完全取决于您的应用程序设计。例如,我个人只会在以下情况下引入抽象基类:
- 我可以在各个类之间共享一些通用代码
- 我需要某种方法来确定某个特定的类属于某个特定类型的族,即
是香蕉
的一种类型水果
除此之外,我可能几乎总是选择接口类型方法。请记住,两者都可以,没有理由不能有一个支持特定接口的抽象基类…不要返回
对象,而是返回IFruits
。另外,重命名静态方法,因为它返回的是水果,而不是它们的重量:
private static IFruits GetFruit(FruitsList fruitNumber)
{
switch (fruitNumber)
{
case FruitsList.Banana:
return new Banana();
case FruitsList.Apple:
return new Apple();
}
return null; // Maybe you can throw a ArgumentException here
}
...
var theFruit = GetFruit(fruits);
var weight = theFruit.ReturnFruitWeight();
对于抽象类
与接口
,这两个选项都有效。如果您不想为方法提供默认实现,那么接口可能会更好,因为您可以实现多个接口,但不能从多个类继承。不要返回对象,而是返回IFruits
。另外,重命名静态方法,因为它返回的是水果,而不是它们的重量:
private static IFruits GetFruit(FruitsList fruitNumber)
{
switch (fruitNumber)
{
case FruitsList.Banana:
return new Banana();
case FruitsList.Apple:
return new Apple();
}
return null; // Maybe you can throw a ArgumentException here
}
...
var theFruit = GetFruit(fruits);
var weight = theFruit.ReturnFruitWeight();
对于抽象类
与接口
,这两个选项都有效。如果您不想为方法提供默认实现,那么接口可能会更好,因为您可以实现多个接口,但不能从多个类继承。我会这样做:
public interface IFruit
{
string Name { get; set; }
decimal GetWeight();
}
public class Fruit : IFruit
{
protected decimal Weight;
public string Name { get; set; }
public decimal GetWeight()
{
return Weight;
}
}
public class Apple : Fruit
{
public Apple()
{
Name = "Granny Smith";
Weight = (decimal) 2.1;
}
}
public class Banana : Fruit
{
public Banana()
{
Name = "Cavendish";
Weight = (decimal) 1.5;
}
}
public enum FruitType
{
Apple,
Banana
}
public static class FruitFactory
{
public static IFruit CreateFruit(FruitType f)
{
switch(f)
{
case FruitType.Banana: return new Banana();
case FruitType.Apple: return new Apple();
default: return null;
}
}
}
class Program
{
static void Main(string[] args)
{
var apple = FruitFactory.CreateFruit(FruitType.Apple);
var banana = FruitFactory.CreateFruit(FruitType.Banana);
Console.WriteLine(apple.Name + " " + apple.GetWeight());
Console.WriteLine(banana.Name + " " + banana.GetWeight());
}
}
我会这样做:
public interface IFruit
{
string Name { get; set; }
decimal GetWeight();
}
public class Fruit : IFruit
{
protected decimal Weight;
public string Name { get; set; }
public decimal GetWeight()
{
return Weight;
}
}
public class Apple : Fruit
{
public Apple()
{
Name = "Granny Smith";
Weight = (decimal) 2.1;
}
}
public class Banana : Fruit
{
public Banana()
{
Name = "Cavendish";
Weight = (decimal) 1.5;
}
}
public enum FruitType
{
Apple,
Banana
}
public static class FruitFactory
{
public static IFruit CreateFruit(FruitType f)
{
switch(f)
{
case FruitType.Banana: return new Banana();
case FruitType.Apple: return new Apple();
default: return null;
}
}
}
class Program
{
static void Main(string[] args)
{
var apple = FruitFactory.CreateFruit(FruitType.Apple);
var banana = FruitFactory.CreateFruit(FruitType.Banana);
Console.WriteLine(apple.Name + " " + apple.GetWeight());
Console.WriteLine(banana.Name + " " + banana.GetWeight());
}
}
您可以遵循抽象类型或接口方法来实现工厂方法。例如,您的案例可以通过抽象来解决,因为您打算返回一个子类
//Fruit base
public abstract class Fruit
{
protected abstract string GetWeight();
}
public class Apple:Fruit
{
protected override string GetWeight()
{
return "I am from Apple";//replace with your implementation
}
}
public class Banana : Fruit
{
protected override string GetWeight()
{
return "I am from Banana";//replace with your implementation
}
}
private static Fruit GetFruitWeight(string fruitNumber)
{
switch (fruitNumber)
{
case "Banana":
return new Banana();
case "Apple":
return new Apple();
}
return null;
}
现在我们应该在哪里使用接口方法
就我个人而言,我在工厂方法中遵循接口方法,希望返回服务。例如,假设一个工厂方法返回一个电子邮件发送者服务,我可以为outlook或其他一些电子邮件服务实现服务
public class Outlook:ISender
{
public void SendEmail()
{
//Write implementation on how OL send email.
}
}
public class OtherEmail : ISender
{
public void SendEmail()
{
//Write implementation on how other email send email.
}
}
public interface ISender
{
void SendEmail();
}
public class EmailFactory
{
public static ISender GetEmailProvider(string type)
{
if (type == "outlook")
return new Outlook();
return new OtherEmail();
}
}
您可以遵循抽象类型或接口方法来实现工厂方法。例如,您的案例可以通过抽象来解决,因为您打算返回一个子类
//Fruit base
public abstract class Fruit
{
protected abstract string GetWeight();
}
public class Apple:Fruit
{
protected override string GetWeight()
{
return "I am from Apple";//replace with your implementation
}
}
public class Banana : Fruit
{
protected override string GetWeight()
{
return "I am from Banana";//replace with your implementation
}
}
private static Fruit GetFruitWeight(string fruitNumber)
{
switch (fruitNumber)
{
case "Banana":
return new Banana();
case "Apple":
return new Apple();
}
return null;
}
现在我们应该在哪里使用接口方法
就我个人而言,我在工厂方法中遵循接口方法,希望返回服务。例如,假设一个工厂方法返回一个电子邮件发送者服务,我可以为outlook或其他一些电子邮件服务实现服务
public class Outlook:ISender
{
public void SendEmail()
{
//Write implementation on how OL send email.
}
}
public class OtherEmail : ISender
{
public void SendEmail()
{
//Write implementation on how other email send email.
}
}
public interface ISender
{
void SendEmail();
}
public class EmailFactory
{
public static ISender GetEmailProvider(string type)
{
if (type == "outlook")
return new Outlook();
return new OtherEmail();
}
}
我觉得水果列表的名字有点不对。您将其称为列表,但在将其传递给GetFruitWeight
时,将其用作标量(单个项目)。是晚餐吗