简体   繁体   English

不使用接口 C# 实现 FactoryPattern

[英]Implementing FactoryPattern without using an Interface C#

I have a requirement of refactoring the code where I have multiple classes and the object of the classes need to be created dynamically depending upon the user request.我需要重构我有多个类的代码,并且需要根据用户请求动态创建类的对象。 Now the classes are all there and have no common methods within them that match each other.现在这些类都在那里,并且它们之间没有相互匹配的通用方法。 So I cannot add an interface to it and create a factory class that will return the interface reference referencing the actual class.因此,我无法向其添加接口并创建一个工厂类,该类将返回引用实际类的接口引用。 Is there a way with generics or any other way to refactor this to be able to create objects dynamically.有没有办法使用泛型或任何其他方式来重构它以便能够动态创建对象。 The approach we have now is that there is a main class where the object of each class is instantiated and all methods are being called.我们现在的方法是有一个主类,其中每个类的对象都被实例化并且所有方法都被调用。 Can we implement a factory pattern without an interface or any solution to my scenario ?我们可以在没有接口或任何解决方案的情况下实现工厂模式吗? Please.请。

Adding sample code to explain the scenario.添加示例代码以解释该场景。

 public interface ITest
{
    string TestMethod1(string st, int ab);
    int TestMethod2(string st);
    void TestMethod4(int ab);
    float ITest.TestMethod3(string st);
}
public class Class1 : ITest
{
    public string TestMethod1(string st, int ab)
    {
        return string.Empty;
    }
    public void TestMethod4(int ab)
    {
        throw new NotImplementedException();
    }

    public int TestMethod2(string st)
    {
        throw new NotImplementedException();
    }

    public float TestMethod3(string st)
    {
        throw new NotImplementedException();
    }
}
 public class Class2 : ITest
{

    float ITest.TestMethod3(string st)
    {
        return float.Parse("12.4");
    }

    void ITest.TestMethod4(int ab)
    {
        throw new NotImplementedException();
    }
    public string TestMethod1(string st, int ab)
    {
        throw new NotImplementedException();
    }

    public int TestMethod2(string st)
    {
        throw new NotImplementedException();
    }
}
 public class Main
{
    ITest test = null;

    public ITest CreateFactory(TestType testType)
    {
        switch(testType)
        {
            case TestType.Class1:
               test = new Class1();
                break;
            case TestType.Class2:
                test = new Class2();
                break;
        }
        return test;
    }
}

enum TestType
{
    Class1,
    Class2
}

So, as in above, I can't have the interface because no common methods are in it.因此,如上所示,我无法拥有该接口,因为其中没有通用方法。 So what other solutions I can have, if I have an empty interface or abstract method, how will that help.那么我还有什么其他解决方案,如果我有一个空的接口或抽象方法,那会有什么帮助。 Even if I put one common method in the interface and all classes implement it, since I am passing the reference to the interface, I can only access the common method from the interface reference.即使我在接口中放了一个通用方法并且所有类都实现了它,但由于我将引用传递给接口,因此我只能从接口引用中访问通用方法。

My idea is to use something like the below, but not sure what the return type would or should be defined as.我的想法是使用类似下面的内容,但不确定返回类型将或应该定义为什么。

 public T CreateFactory(TestType testType)
    {
        switch(testType)
        {
            case TestType.Class1:
               return GetInstance<Class1>("Class1");

            case TestType.Class2:
                return GetInstance<Class1>("Class2");

        }
        return null;
    }
    public T GetInstance<T>(string type)
    {
        return (T)Activator.CreateInstance(Type.GetType(type));
    }

How do I define T here in the return is my concern and how can I invoke it, if anybody can help with that, then I think I am close to the solution.我如何在返回中定义 T 是我关心的问题,我该如何调用它,如果有人可以提供帮助,那么我想我已经接近解决方案了。

Answer to my problem回答我的问题

public static T CreateFactory<T>()
    where T: IFactory, new()
{
    return new T();
}

I'm not saying totally understand the problem, but give it a shot...我不是说完全理解这个问题,但试一试......

Factory like class that you have:您拥有的类似工厂的课程:

class Factory
{
    public static Visitable Create(string userInput)
    {
        switch (userInput)
        {
            case nameof(ClassA):
                return new ClassA();
            case nameof(ClassB):
                return new ClassB();
            default:
                return null;
        }
    }
}

Types that you have to create:您必须创建的类型:

class ClassA : Visitable
{
    public void M1(){}
    public override void Accept(Visitor visitor){visitor.Visit(this)}
}

class ClassB : Visitable
{
    public void M2(){}
    public override void Accept(Visitor visitor){visitor.Visit(this)}
}

Usage of the code:代码的使用:

var visitor = new Visitor();
var obj = Factory.Create("ClassA");
obj.Accept(visitor);

And the missing parts:和缺失的部分:

class Visitor
{
    public void Visit(ClassA obj){ obj.M1(); } // Here you have to know what method will be called!
    public void Visit(ClassB obj){ obj.M2(); } // Here you have to know what method will be called!
}

abstract class Visitable
{
    public abstract void Accept(Visitor visitor);
}

This is called the Visitor pattern.这称为访问者模式。 If you know what methods need to be called Visitor.Visit than that is what you want.如果您知道哪些方法需要调用 Visitor.Visit,那么这就是您想要的。

I don't entirely understand your question but a basic assertion is wrong.我不完全理解你的问题,但一个基本的断言是错误的。 I am concerned with your design given the basis of your question.鉴于您提出的问题,我很关心您的设计。

Regardless, my proposed solution:无论如何,我提出的解决方案:

You are saying that you don't have a common object (indirect, directly you stated: "I can't have the interface because no common methods are in it."你是说你没有公共对象(间接,你直接说:“我不能有接口,因为里面没有公共方法。”

object is the common element. object是公共元素。

I don't condone this but you could create a factory object that just returned object as the data type.我不同意这种做法,但您可以创建一个工厂对象,该对象仅将object作为数据类型返回。 The problem with this is you then have to cast it after the object creation which you may not mind...这样做的问题是您必须在创建对象之后进行转换,您可能不介意......

internal class MyFactory
{
    internal object CreateItem1() { return ...; }
    internal object CreateItem2() { return ...; }
    internal object CreateItem2(ExampleEnum e) 
    {
        switch(e) 
        {
            case e.Something:
               return new blah();
            default:
               return new List<string>();
        }
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM