我有几个类的代码都非常相似,我想知道合并通用代码是否有意义,以及如何进行处理。每个类都有一个特定的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,但后来我担心,这取决于从何处调用该属性。
答案 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();
}
}