1

I have a helper class which has a method that perform some checks against a field in a model. I have two models, ModelA and ModelB, they have some similarities but not all. One of them is they both have a field, lets say string ProductCheckField. The ProductCheckMethod returns back the Model, because of that it has created duplication of methods which does the same thing but returns a different model. Even the extracted methods are duplicates. Is there a good design pattern or any other good practice/technique I can use to eliminate duplication of having to create two methods?

N.B I can't use a shared Interface as the models are not the same.

Currently I have..

public class ModelA
 string blah..
 int blah
 .....
 string ProductCheckField
public class ModelB
 string xyz
 int xyz
 .....
 string ProductCheckField
public class HelperClass
{
 public ModelA ProductCheckMethod(ModelA model)
 {
 /// do somthing
 performX(model);
 checkY(model);
 return model;
 }
 public ModelB ProductCheckMethod(ModelB model)
 {
 /// do somthing
 performXDuplicate(model);
 checkYDuplicate(model);
 return model;
 }
}
asked Jan 14, 2015 at 17:37
5
  • Why does check return the model? Commented Jan 14, 2015 at 17:40
  • @Telastyn Because as part of the check it updates the model and returns back Commented Jan 14, 2015 at 17:44
  • Okay, so if ModelA and ModelB have duplicate checks, why are the duplicate bits not shared in some third class? Commented Jan 14, 2015 at 17:48
  • @Telastyn Because you will be passing in the model to perform those check. Therfore, even if they are in a third class it will still need a model passed in. And as mentioned, these models are different apart from some of the fields Commented Jan 14, 2015 at 17:50
  • 1
    Sure, but if "some of the fields" are put into a common class, they could be checked using the same function, instead of duplicating check(modelA.X); check(modelA.Y), check(modelB.X); check(modelB.Y) and the such. Without more concrete examples, it's hard to say. Commented Jan 14, 2015 at 17:53

4 Answers 4

0

What you have shown of the Models shows the same interface. So your protestations of differences are unsupported by the example you give. I suggest you wrap the fields you check in performX and checkY with accessor methods that are commonly named across model A and B and extract a common interface for the use of your Helper class.

public interface CheckModel
{
 public String getStringValue();
 public void setStringValue(String blahs);
 public int getIntValue();
 public void setIntValue(int blah);
 public String getProductCheckField();
 public void setProductCheckField(String productCheckField);
}
public class ModelA implements CheckModel
{
 String blahs;
 int blah;
 String ProductCheckField;
 public String getStringValue()
 {
 return blahs;
 }
 public void setStringValue(String blahs)
 {
 this.blahs = blahs;
 }
 public int getIntValue()
 {
 return blah;
 }
 public void setIntValue(int blah)
 {
 this.blah = blah;
 }
 public String getProductCheckField()
 {
 return ProductCheckField;
 }
 public void setProductCheckField(String productCheckField)
 {
 ProductCheckField = productCheckField;
 }
}
public class ModelB implements CheckModel
{
 String xyzs;
 int xyz;
 String ProductCheckField;
public String getStringValue()
{
 return xyzs;
}
public void setStringValue(String xyzs)
{
 this.xyzs = xyzs;
}
public int getIntValue()
{
 return xyz;
}
public void setIntValue(int xyz)
{
 this.xyz = xyz;
}
public String getProductCheckField()
{
 return ProductCheckField;
}
public void setProductCheckField(String productCheckField)
{
 ProductCheckField = productCheckField;
}
}
public class HelperClass
{
 public CheckModel ProductCheckMethod(CheckModel model)
 {
 /// do somthing
 performX(model);
 checkY(model);
 return model;
 }
 private void checkY(CheckModel model)
 {
 // ...
 }
 private void performX(CheckModel model)
 {
 // ...
 }
}
answered Jan 22, 2015 at 1:55
2

You seem to have some sort of mental block going on. If you want a design that eliminates the duplication, you're going to have to change your design somehow, which you seem resistant to do. You need to look past your current design.

Some ways to eliminate the duplication, some of which are better than others:

  • Put the common stuff of the models into a common class, with your models containing a reference to that object, as Telastyn suggested in the comments.
  • Reverse of Telastyn's suggestion, where you have a ProductCheckStuff class, with pointers inside it to one of the models.
  • Use generics in HelperClass or its methods, with the model as the generic parameter.
  • Have each model implement an interface with getters for the fields you need.
  • Extend the model from a base class that implements the ProductCheckMethod.
  • Put the product check fields and methods into a mixin (if your language supports it) that is mixed in with the other fields of your model.

You can't make an omelette without breaking some eggs. You have a ton of choices here. Keep trying them until you find one that works.

answered Jan 14, 2015 at 18:32
0

It's hard to understand fully what you need done here. It looks like you MIGHT have a case for the Visitor pattern but you said you can't use the same interface.

The only other alternative would be the Strategy pattern where the CheckMethod would be implemented in a strategy class for each Model and instead of the overloaded methods you can use generics to map the Model to the strategy.

public class HelperClass
{
 public T CheckMethod(T model)
 {
 var strategy GetStrategyFor(typeof(T));
 var result = strategy.Execute(model);
 return result;
 }
}

You could use an IoC container or other methods for determining how a type maps to a given strategy. But once you've done that, you can add new models and matching strategies to your heart's content.

answered Jan 14, 2015 at 18:35
0

With the constrints you having (unable to use a common interface) for ModelA and for ModelB, there isn't a lot of things you can do from the Models. However you could generalize the helper class.

One way to do is,

public class RequestDTO
{
 string xyz_blah;
}
public class ResultDTO. 
{
 string ProductCheckField; 
}
public class HelperClass
{
 public static ResultDTO ProductCheckMethod(RequestDTO request)
 {
 //do something
 ResultDTO result = performXUsingRequestData(model);
 checkYUsingRequestData(model,result);
 return result;
 } 
}

Here the data you currently sending to the methods performX,checkY are added to the RequestDTO and whatever the data you want to update on the model are added to the ResultDTO.

In your model you could call the helper class like this,

public class ModelA
{
 string blah..
 int blah
 .....
 string ProductCheckField
 public void ProductCheckMethod()
 {
 RequestDTO dto = new RequestDTO { xyz_blah = blah; }
 ResultDTO result = HelperClass.ProductCheckMethod(dto);
 ProductCheckField = result.ProductCheckField;
 }
}

Same goes for the ModelB

answered Jan 22, 2015 at 3:31

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.