What is a good pattern to refactor a chunk of code where you can identify smaller chunks, but the results of these smaller chunks are used in other chunks?
An example should make things more clear. Let's say you have something like this (reduced in size to make things easier):
public Response CreateCustomer(CreateCustomerDTO input)
{
var customerGroup = GetCustomerGroup(input.GroupId);
if (customerGroup == null)
{
return new InvalidCustomerGroupResponse();
}
if (customerGroup.HasReachedMaxAmountOfCustomers()
{
return new InvalidCustomerGroupResponse();
}
var segment = SegmentService.GetSegment(input.SegmentId);
if (!segment.CanAcceptCustomer(input.Country))
{
return new CannotAddCustomerToSegmentResponse();
}
// More segment checks
CustomerService.CreateCustomer(input.Name, input.Country, customerGroup, segment);
return new SuccessResponse();
}
You might find all sorts of things can be improved in this code, but I totally made it up. The key thing is to demonstrate a structure. Plus, the real code is many times longer. We can identify separate chunks. Ideally, I'd want to refactor it into something like this:
public Response CreateCustomer(CreateCustomerDTO input)
{
CheckGroup(input);
CheckSegment(input);
CustomerService.CreateCustomer(input.Name, input.Country, customerGroup, segment);
return new SuccessResponse();
}
But of course, the chunk that does the checks also retrieves some data that the subsequent chunks need. So I end up with something like this:
public Response CreateCustomer(CreateCustomerDTO input)
{
var customerCheckResponseCode = CheckCustomer(input.GroupId);
if (customerCheckResponseCode != ResponseCode.OK)
{
return new InvalidCustomerGroupResponse();
}
var segmentCheckResponseCode = CheckSegment(input.SegmentId);
if (segmentCheckResponseCode != ResponseCode.OK)
{
return new CannotAddCustomerToSegmentResponse();
}
CustomerService.CreateCustomer(input.Name, input.Country, customerGroup, segment);
return new SuccessResponse();
}
This is only marginally better. It's readable here, but in my real code, there are many lines I could group into chunks. Things I can logically group, but I can't hide everything in separate methods because some variables I need in other logical groups as well. So I can't refactor out all those if checks for example. Unless someone knows a better pattern for this problem?
InvalidCustomerGroupResponse
?