本文介绍了类型铸造和工厂模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难想出如何在DTO映射器中实现一个工厂模式,我正在尝试创建它。我很确定我需要重新思考我的设计。以下是我正在运行的一个很小的例子:

  public abstract class Person 
{
public string Name {get;组; }
public decimal Salary {get;组;


public class Employee:Person
{
public Employee()
{
this.Salary = 20000;
}

}

public class Pilot:Person
{
public string PilotNumber {get;组; }

public Pilot()
{
this.Salary = 50000;
}
}

public static class PersonFactory
{
public static Person CreatePerson(string typeOfPerson)
{
switch typeOfPerson)
{
caseEmployee:
return new Employee();
casePilot:
return new Pilot();
默认值:
返回新的Employee();
}
}
}

并使用工厂:

  Person thePilot = PersonFactory.CreatePerson(Pilot); 
((Pilot)thePilot).PilotNumber =123ABC;

如何在没有打字的情况下加载飞行员号码?这是错误的做法吗?我可以把飞行员号码放在人类,但是员工会继承这个号码,而不是我想要的。我可以做什么?



谢谢!



-Jackson

解决方案

您可以为您的PersonFactory类添加特定类型的方法,或添加一个通用的 CreatePerson< T>() ,但是如果调用者已经知道应该接收什么类型的人,那将是有用的。也许这是这种情况,或者也许没有。



在这种情况下,我希望实际上调用PersonFactory.CreatePerson的代码不会知道或关心什么样的人被归还。如果你有一些代码,那个点已经知道了,或者弄清楚你有什么类型的人物,那么你只需要转换它。



下面是一个代码例如说明了您可以在工厂和不同的使用情况下做什么,尝试解释什么时候您只需要投放或不需要投放。

  public static class PersonFactory 
{
public static Person CreatePerson()
{
return new Person();
}

public static Employee CreateEmployee()
{
return new Employee();
}

public static Pilot CreatePilot()
{
return new Pilot();


public static T CreatePerson< T>()
其中T:Person
{
return(T)CreatePerson(typeof(T) ;


public static Person CreatePerson(Type type)
{
if(type == typeof(Person))
return CreatePerson();
else if(type == typeof(Employee))
return CreateEmployee();
else if(type == typeof(Pilot))
返回CreatePilot();
else
throw new ArgumentOutOfRangeException(string.Format(CultureInfo.InvariantCulture,Unrecognized type [{0}],type.FullName),type);
}

public static Person CreatePerson(string typeOfPerson)
{
switch(typeOfPerson)
{
caseEmployee:
return CreateEmployee();
casePilot:
return CreatePilot();
默认值:
返回CreateEmployee();
}
}
}



class UsageExample
{
Person GetPerson()
{
Pilot p;
p =(Pilot)PersonFactory.CreatePerson(Pilot); //这个代码已经知道要期待一个Pilot,所以为什么不只是调用CreatePilot或者CreatePerson&Pi Pi>()?
p = PersonFactory.CreatePilot();
p = PersonFactory.CreatePerson< Pilot>();
return p;
}

Person GetPerson(type personType)
{
Person p = PersonFactory.CreatePerson(personType);
//这段代码不知道刚刚创建了什么类型的人,因为它取决于参数
return p;
}

void KnowledgableCaller()
{
键入personType = typeof(Pilot);

Person p = this.GetPerson(typeof(Pilot));
//这段代码知道刚刚返回的Person对象应该是Pilot类型

Pilot pilot =(Pilot)p;
//继续访​​问特务功能
}

void IgnorantCaller()
{
Person p = this.GetPerson();
//这个调用者不知道刚刚返回的Person对象的类型

//但是它可以执行测试来计算出
Pilot pilot = p作为Pilot;
if(pilot!= null)
{
//继续访​​问飞行员专用功能
}
}
}


I'm having a hard time figuring out how to implement a factory pattern in a DTO mapper I'm trying to create. I'm pretty sure I need to rethink my design. Here is a very small example of what I'm running in to:

    public abstract class Person
{
    public string Name { get; set; }
    public decimal Salary { get; set; }
}

public class Employee : Person
{
    public Employee()
    {
        this.Salary = 20000;
    }

}

public class Pilot : Person
{
    public string PilotNumber { get; set; }

    public Pilot()
    {
        this.Salary = 50000;
    }
}

public static class PersonFactory
{
    public static Person CreatePerson(string typeOfPerson)
    {
        switch (typeOfPerson)
        {
            case "Employee":
                return new Employee();
            case "Pilot":
                return new Pilot();
            default:
                return new Employee();
        }
    }
}

and to use the factory:

Person thePilot = PersonFactory.CreatePerson("Pilot");
        ((Pilot)thePilot).PilotNumber = "123ABC";

How do I get around loading the pilot number without typecasting it to Pilot?? is this the wrong way to do this? I could put the pilot number in the Person class, but then Employee would inherit the number and that's not what I want. What can I do?

Thanks!

-Jackson

解决方案

You could add methods for specific types to your PersonFactory class, or add a generic CreatePerson<T>() method, but that would only be useful if the caller already knows what type of person it should be receiving. Maybe this is the case, or maybe not.

With this scenario, I'd expect that the code that is actually making the call to PersonFactory.CreatePerson would not know or care what kind of person is being returned. If you have some code after that point that already knows or figures out what type of person object you have, then you will simply have to cast it.

Below is a code example that illustrates what you could do on your factory and different usage scenarios, attempting to explain when you simply need to cast or when you don't.

public static class PersonFactory
{
    public static Person CreatePerson()
    {
        return new Person();
    }

    public static Employee CreateEmployee()
    {
        return new Employee();
    }

    public static Pilot CreatePilot()
    {
        return new Pilot();
    }

    public static T CreatePerson<T>()
        where T : Person
    {
        return (T)CreatePerson(typeof(T));
    }

    public static Person CreatePerson(Type type)
    {
        if (type == typeof(Person))
            return CreatePerson();
        else if (type == typeof(Employee))
            return CreateEmployee();
        else if (type == typeof(Pilot))
            return CreatePilot();
        else
            throw new ArgumentOutOfRangeException(string.Format(CultureInfo.InvariantCulture, "Unrecognized type [{0}]", type.FullName), "type");
    }

    public static Person CreatePerson(string typeOfPerson)
    {
        switch (typeOfPerson)
        {
            case "Employee":
                return CreateEmployee();
            case "Pilot":
                return CreatePilot();
            default:
                return CreateEmployee();
        }
    }
}



class UsageExample
{
    Person GetPerson()
    {
        Pilot p;
        p = (Pilot)PersonFactory.CreatePerson("Pilot"); // this code already knows to expect a Pilot, so why not just call CreatePilot or CreatePerson<Pilot>()?
        p = PersonFactory.CreatePilot();
        p = PersonFactory.CreatePerson<Pilot>();
        return p;
    }

    Person GetPerson(Type personType)
    {
        Person p = PersonFactory.CreatePerson(personType);
        // this code can't know what type of person was just created, because it depends on the parameter
        return p;
    }

    void KnowledgableCaller()
    {
        Type personType = typeof(Pilot);

        Person p = this.GetPerson(typeof(Pilot));
        // this code knows that the Person object just returned should be of type Pilot

        Pilot pilot = (Pilot)p;
        // proceed with accessing Pilot-specific functionality
    }

    void IgnorantCaller()
    {
        Person p = this.GetPerson();
        // this caller doesn't know what type of Person object was just returned

        // but it can perform tests to figure it out
        Pilot pilot = p as Pilot;
        if (pilot != null)
        {
            // proceed with accessing Pilot-specific functionality
        }
    }
}

这篇关于类型铸造和工厂模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-25 20:40