简体   繁体   中英

Passing variables to methods with often changing parameter list

I am using a MVC model in php. The controller is sending data to the model and sometimes it expects something back. As I write my webpage I add utilities which needs more information from the model. Mostly it makes controller pass more arguments to the model interface. The problem is that model interface mostly only passes those variables to another methods, so the parameter list should be changed in a few places. This obviously is unacceptable so how should it be handled? I think that passing the array of data isn't the best idea because it can make it uncontrollable. Anything could add anything to that. Currently I am using another solution. I create special class to handle this. Every one of them derives from a class containing something like "getAsArray()" method. I think that creating a special class for nearly every controller need is a waste of time and resources so here is my question: What is the best solution to this problem? What are the common ideas?

Controller

 public function addUser(){
   $this->load->model("User"); 
   $username = $this->someWayOfGettingData("username");
   $email = $this->someWayOfGettingData("email");
   $password = $this->someWayOfGettingData("password");
   $this->User->insert($username, $email, $password);
}

Model

private function someMethodOperatingOnData($username, $email, $password){
   $answer = $this->queryAdd($username, $email, $password);
   return $answer;
}

public function insert($username, $email, $password){
   return $this->someMethodOperatingOnData($username, $email, $password); 
}

What's the problem: When I decide to add another information about user (eg gender) I have to update the list of parameters in

insert($username, $email, $password);
someMethodOperatingOnData($username, $email, $password);
queryAdd($username, $email, $password);

to:

insert($username, $email, $password, $gender);
someMethodOperatingOnData($username, $email, $password, $gender);
queryAdd($username, $email, $password, $gender);

So I have to update every function passing those variables. I could use an array:

insert($arrayOfData);
someMethodOperatingOnData($arrayOfData);
queryAdd($arrayOfData);

But anywhere anything can add or remove those variables and I don't want that to happed.

I can think of different strategies for this:

1) As you are currently doing, create a custom class, instantiate it with your parameters, pass it over. However, since parameter list keep changing, your plain-old-data classes are going to be moving targets, ie costly.

2) You can create a dictionary and put those parameters into this dictionary and pass it along. It is an anti-pattern in the OO world, but it could be a reasonable solution for you.

3) In Django world, one of the best practices is to pass the request altogether. This approach keeps your method signatures clean. This is more favorable compared to #2 above.

I hope it helps.

EDIT I am not a PHP guy. Think about dictionaries as key value pairs. In PHP, arrays are actually key-value pairs. So, you can use arrays in PHP lingo, or Dictionaries in other languages like Smalltalk. So this option still holds, although the terminology I picked was not 100% correct, the idea or principal is still the same.

The following is an excerpt from the book named Two Scoops of Django section 9-2:

For many utility functions, we are taking an attribute or attributes from the django.http.HttpRequest (or HttpRequest for short) object and gathering data or per- forming operations. What we've found is by having the request object itself as a primary argument, we have simpler arguments on more methods. is means less cognitive overload of managing function/method arguments: just pass in the HttpRequest object!

EDIT2

I have just seen the edit you made to your question. So, from the example you gave, what seems to be happening is you have a user class. As time passes by, there might be a need to add more properties to the user class. For example, 20 years ago, there was no such property as MobilePhone, but now it is almost mandatory. So, naturally the best way is to add that member property to your User class. Instantiate it with proper data and pass the User object, not individual user properties Until you can instantiate a User Object, you can pass around the request Object as mentioned in #3, afterwards, you can use the User object. I believe this is your best route.

Cheers,

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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