gpt4 book ai didi

c# - 没有开关或 If/Then 的工厂模式

转载 作者:IT王子 更新时间:2023-10-29 04:49:41 26 4
gpt4 key购买 nike

我正在寻找一个如何实现工厂类的简单示例,但没有使用 Switch 或 If-Then 语句。我能找到的所有示例都使用一个。例如,如何修改这个简单的示例(如下),使实际的工厂不依赖于 Switch?在我看来,这个例子违反了开闭原则。我希望能够添加具体类(“经理”、“职员”、“程序员”等)而无需修改工厂类。

谢谢!

class Program
{
abstract class Position
{
public abstract string Title { get; }
}

class Manager : Position
{
public override string Title
{
get { return "Manager"; }
}
}

class Clerk : Position
{
public override string Title
{
get { return "Clerk"; }
}
}

class Programmer : Position
{
public override string Title
{
get { return "Programmer"; }
}
}

static class Factory
{
public static Position Get(int id)
{
switch (id)
{
case 0: return new Manager();
case 1: return new Clerk();
case 2: return new Programmer();
default: return new Programmer();
}
}
}

static void Main(string[] args)
{
for (int i = 0; i <= 2; i++)
{
var position = Factory.Get(i);
Console.WriteLine("Where id = {0}, position = {1} ", i, position.Title);
}
Console.ReadLine();
}
}

更新:

哇!感谢大家!我学到了很多。在审查了所有反馈后,我混合了一些答案并得出了这个结论。我愿意就更好的方法进行进一步对话。

class Program
{

public interface IPosition
{
string Title { get; }
}

class Manager : IPosition
{
public string Title
{
get { return "Manager"; }
}
}

class Clerk : IPosition
{
public string Title
{
get { return "Clerk"; }
}
}

class Programmer : IPosition
{
public string Title
{
get { return "Programmer"; }
}
}

static class PositionFactory
{
public static T Create<T>() where T : IPosition, new()
{
return new T();
}
}


static void Main(string[] args)
{

IPosition position0 = PositionFactory.Create<Manager>();
Console.WriteLine("0: " + position0.Title);

IPosition position1 = PositionFactory.Create<Clerk>();
Console.WriteLine("1: " + position1.Title);

IPosition position2 = PositionFactory.Create<Programmer>();
Console.WriteLine("1: " + position2.Title);

Console.ReadLine();
}
}

另一个编辑:

也可以使用未知类型创建接口(interface)实例:

static class PositionFactory
{
public static IPosition Create(string positionName)
{
Type type = Type.GetType(positionName);
return (IPosition)Activator.CreateInstance(type);
}
}

然后可以按如下方式调用:

IPosition position = PositionFactory.Create("Manager");
Console.WriteLine(position.Title);

最佳答案

这个怎么样(不需要字典,请注意,如果您尝试 Create<Position>() 会出现语法错误):

编辑 - 更新为使用显式实现的 IPosition 接口(interface)。只有 IPosition 的实例可以访问成员函数(例如 <implementation of Manager>.Title 将无法编译)。

编辑 #2 Factory.Create 在正确使用界面时应该返回 IPosition 而不是 T。

using System;
using System.Collections.Generic;

class Program
{
interface IPosition
{
string Title { get; }
bool RequestVacation();
}

class Manager : IPosition
{
string IPosition.Title
{
get { return "Manager"; }
}

bool IPosition.RequestVacation()
{
return true;
}
}

class Clerk : IPosition
{
int m_VacationDaysRemaining = 1;

string IPosition.Title
{
get { return "Clerk"; }
}

bool IPosition.RequestVacation()
{
if (m_VacationDaysRemaining <= 0)
{
return false;
}
else
{
m_VacationDaysRemaining--;
return true;
}
}
}

class Programmer : IPosition
{
string IPosition.Title
{
get { return "Programmer"; }
}

bool IPosition.RequestVacation()
{
return false;
}
}

static class Factory
{
public static IPosition Create<T>() where T : IPosition, new ()
{
return new T();
}
}

static void Main(string[] args)
{
List<IPosition> positions = new List<IPosition>(3);
positions.Add(Factory.Create<Manager>());
positions.Add(Factory.Create<Clerk>());
positions.Add(Factory.Create<Programmer>());

foreach (IPosition p in positions) { Console.WriteLine(p.Title); }
Console.WriteLine();

Random rnd = new Random(0);
for (int i = 0; i < 10; i++)
{
int index = rnd.Next(3);
Console.WriteLine("Title: {0}, Request Granted: {1}", positions[index].Title, positions[index].RequestVacation());
}

Console.ReadLine();
}
}

关于c# - 没有开关或 If/Then 的工厂模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33878216/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com