当属性是不同的对象类型时,将代码合并到基类中

时间:2018-08-03 19:42:28

标签: c# inheritance

我有几个类的代码都非常相似,我想知道合并通用代码是否有意义,以及如何进行处理。每个类都有一个特定的Model属性和一个特定的Service属性,但除此之外,它们几乎是相同的。

以下是我正在使用的代码的示例:

PDReg.prototype.register = function(e) {
  // It's a form submit, don't reload the page
  e.preventDefault();
  var form = this.courseForm;
  var classes = [];
  var uid = firebase.auth().currentUser.uid;

  for (var i=0; i<form.elements.length; i++) {
    // build the object to submit and add to an array
  }

  for (var i=0; i<classes.length; i++) {
    this.coursesRef = this.database.ref('courses/' + classes[i].id + '/members/' + uid);

    // Write the member object to `courses` under the correct key
    this.coursesRef.set({'code': classes[i]['code']}).then(function(classes) {
    // write to the user ref
    firebase.database().ref('users/' + uid + '/regs/' + id).set(true);
    onSuccess(title);
document.getElementById('allCourses').removeChild(document.getElementById(id))
    }, function(e) {
      onFailure(e, title);
    });
  }
};

所以说我有4个类,它们都具有相同的public class Example1 { public Object1 Model { get; set; } private Service1 Service {get;set;} protected bool Create() { try { Model = Service.Create(Model); return true; } catch(Exception ex) { Console.WriteLine(ex.Message); return false; } } } 方法语法,但是属性对象类型都不同。有没有一种方法可以将我转换成4个类,每个类都定义了属性,然后在一个基类中使用了Create()方法?

我希望它看起来像下面这样:

Create()

但是我对如何在基类中提供属性感到困惑。

感谢您的帮助。如果这不可能,那我只是想让我的代码库变得不那么肿。

编辑:

我认为可能有用的一件事是在Base类中将Model和Service定义为Object,但后来我担心,这取决于从何处调用该属性。

4 个答案:

答案 0 :(得分:4)

您可以将泛型与抽象基类一起使用,以达到需要的位置:

public abstract class Base<TModel, TService> where TService: IService
{
    public TModel Model { get; set; }
    private TService Service { get; set; }

    protected bool Create()
    {
        try
        {
            Model = Service.Create(Model);
            return true;
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
            return false;
        }
    }
}

您唯一需要在此处更改的就是向引用为Create()的“服务”类型添加支持抽象。然后,您必须将泛型限制为该抽象(在我上面的示例中,抽象为IService)。您的抽象看起来像这样:

public interface IService
{
    T Create(T input);
}

实现此抽象基类后,您的实现如下:

public class Example1 : Base<Object1, Service1> 
{
    //Code specific to this implementation
}

public class Example2 : Base<Object2, Service2> 
{
    //Code specific to this implementation
}

您永远不会解决的一件事是您的基地实际上将如何获得其内容。您可能必须将这些参数传递给构造函数。我也没有提供,因为您也没有,但是请记住,您至少需要将 服务传递到基础中,以便它可以从传递的服务中调用Create()

答案 1 :(得分:0)

如果Model和Object是同一类,则您的示例将起作用。如果Object1和Object2是不同的类,则可能需要进行一些调整,或者可能无法实现。

如果它们是同一类,则可以将Object变量作为受保护对象,并在每个派生类的构造函数中以不同的方式声明它。

如果它们不是相同的类,而是相似的,则Object1,Object2等类都可以从一个Object类继承,并且上述操作可以相同,但是这将无济于事如果Object1和Object2完全不同。

如果我了解您要执行的操作,则可能会有所帮助:

public class Base
{
  public Object model;
  protected Service service;

  protected bool Create()
  {
          try
        {
            Model = Service.Create(Model);
            return true;
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
            return false;
        }
  }
}
public class Example1 : Base
{
  public Example1() //Assign specifics in constructor
  {
    model = model1;
    service = service1;
  }
}
public class Example2 : Base
{
  public Example2() //Assign specifics in constructor
  {
    model = model2;
    service = service2;
  }
}

如果这没有帮助,那么也许您正在寻找的是抽象类/方法,但是我不确定。

答案 2 :(得分:0)

interface IModel { }

interface IService<out TModel>
{
    TModel Create(IModel model);
}

interface IModelService<TModel, TService> where TModel : IModel where TService : IService<TModel>
{
    TModel Model { get; set; }
    TService Service { get; set; }
}

class ExampleModel : IModel { }

class ExampleService : IService<ExampleModel>
{
    public ExampleModel Create(TModel model)
    {
        return new ExampleModel();
    }
}

class Example : ExampleBase<ExampleModel, ExampleService>
{

}

abstract class ExampleBase<TModel, TService> : IModelService<TModel, TService> where TModel : IModel where TService : IService<TModel>
{
    public TModel Model { get; set; }
    public TService Service { get; set; }

    protected bool Create()
    {
        //do what you must
    }
}

具有泛型类型参数和少量用于定义和约束接口的抽象类

答案 3 :(得分:0)

您可以使用Template_method_pattern解决问题的另一种方法,因为每个子类都有自己的Sevice对象。

使IService接口成为Service类合同。 TModel Create<TModel>(TModel model);中有一个合同IService

public interface IService {
    TModel Create<TModel>(TModel model);
}

然后让Base类成为具有泛型的抽象类,它可以让子类继承,并使用hang方法protected abstract IService GetService();来让子类提供Service对象。

public abstract class Base<TModel> 
{
    public TModel Model { get; set; }
    protected abstract IService GetService();

    protected bool Create()
    {
        IService service = GetService();
        try
        {
            Model = service.Create(Model);
            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            return false;
        }
    }
}

您的子类可以继承Base<Object1>并设置其Model类型,并提供属于该类的服务对象。

public class Example1 : Base<Object1>
{
    protected override IService GetService()
    {
        return new Service1();
    }
}