For example, for oauth, I may need to copy and paste oauth and oauth callback code like it (assume Client is the framework I use, I don't use real framework like google because I want to simplify the code):
sample code:
public function oauth(){
$client=new Client([MY_APP_ID,MY_APP_SECRET]);
$client->setCallbackUrl(SOME_URL);
//some $client settings
header('Location: ' . filter_var($client->getURL(), FILTER_SANITIZE_URL));
}
public function oauth_callback(){
$client=new Client([MY_APP_ID,MY_APP_SECRET]);
$client->setCallbackUrl(SOME_URL);
//some $client settings
if(!$_GET['code']){
//back to oauth and return;
}
$userInfo=$client->getUserInfo();
}
In real code, I would copy and paste sample code like it:
Login:
public function login_oauth(){
$client=new Client([MY_APP_ID,MY_APP_SECRET]);
$client->setCallbackUrl(MY_URL.'login_callback');
//some $client settings
header('Location: ' . filter_var($client->getURL(), FILTER_SANITIZE_URL));
}
public function login_callback(){
$client=new Client([MY_APP_ID,MY_APP_SECRET]);
$client->setCallbackUrl(MY_URL.'login_callback');
//some $client settings
if(!$_GET['code']){
//back to oauth and exit;
}
$userInfo=$client->getUserInfo($_GET['code']);
//check login valid
}
Register:
public function register_oauth(){
$client=new Client([MY_APP_ID,MY_APP_SECRET]);
$client->setCallbackUrl(MY_URL.'register_callback');
//some $client settings
header('Location: ' . filter_var($client->getURL(), FILTER_SANITIZE_URL));
}
public function register_callback(){
$client=new Client([MY_APP_ID,MY_APP_SECRET]);
$client->setCallbackUrl(MY_URL.'register_callback');
//some $client settings
if(!$_GET['code']){
//back to oauth and exit;
}
$userInfo=$client->getUserInfo($_GET['code']);
//check is user already registered
}
I know it is seriously violating DRY principle because I copy and paste code, so I try to extract common parts:
common functions:
public static function createClient($url){
$client=new Client([MY_APP_ID,MY_APP_SECRET]);
$client->setCallbackUrl(URL_PREFIX.$url);
//some $client settings
return $client;
}
public static oauth($url){
$client=MyClass::createClient($url);
header('Location: ' . filter_var($client->getURL(), FILTER_SANITIZE_URL));
}
public static oauth_callback($url){
$client=MyClass::createClient($url);
if(!$_GET['code']){
//back to oauth and exit;
}
$userInfo=$client->getUserInfo($_GET['code']);
return $userInfo;
}
Login:
public function login_oauth(){
oauth('login_callback');
}
public function login_callback(){
$userInfo=oauth_callback('login_callback');
//check login valid
}
Register:
public function login_oauth(){
oauth('login_callback');
}
public function login_callback(){
$userInfo=oauth_callback('login_callback');
//check is user already registered
}
But I found the refactored code is harder to maintain because:
It looks quite different from the sample code, which is less understandable, especially for beginners who never uses this framework before
The newer one has more sub functions, which spends far more time to link the relationship between those sub functions.
When adding new API, using sample code is easy because I just need to copy and paste directly, but if I use my refactored version, I need to study how I refactored the code first.
Refactoring sample code may introduce some new probems, eg: missing some line of codes during copying
The code may be totally replaced by a newer version of sample code, or by other framework
So my question is, is 'Keep it looks similar to sample code' a valid reason to prefer WET over DRY principle?