Page MenuHomePhabricator
Paste P8791

Use trait as an adapter to ease interface changes
ActivePublic

Authored by dcausse on Jul 24 2019, 9:16 AM.
#############
# Initial state we have an extension Thing with a method draw
#############
/////////////
// Core
/////////////
/**
* Thing that can draw
*/
interface Thing {
/**
* @param int $x
*/
public function draw( $x );
}
/**
* Trait used to ease evolution of the Thing interface
*/
trait ThingBCTrait {
}
/**
* Base class for Thing
*/
abstract class BaseThing implements Thing {
use ThingBCTrait;
}
/////////////
// Extension
/////////////
class SimpleThing extends BaseThing {
/**
* @param int $x
*/
public function draw( $x ) {
print( $x );
}
}
class ThingAndThat extends That implements Thing {
use ThingBCTrait;
/**
* @param int $x
*/
public function draw( $x ) {
print( $x );
}
}
####################
# Goal 1: warn extensions that they need to implement draw2
# Goal 2: gently tell call sites to move to draw2
# We introduce draw2 as a replacement of draw
# We soft deprecate draw to gently warn call sites
# We add draw2 with a warning to our BCTrait to not break existing extensions
####################
/////////////
// Core
/////////////
/**
* Thing that can draw
*/
interface Thing {
/**
* @param int $x
* @deprecated use draw2d
*/
public function draw( $x );
/**
* @param int $x
* @param int $y
*/
public function draw2d( $x, $y );
}
/**
* Trait used to ease evolution of the Thing interface
*/
trait ThingBCTrait {
public function draw2d( $x, $y ) {
wfDeprecated( __CLASS__ . " must implement draw2d" );
$this->draw( $x );
}
}
/**
* Base class for Thing
*/
abstract class BaseThing implements Thing {
use ThingBCTrait;
}
/////////////
// Extension
/////////////
class SimpleThing extends BaseThing {
/**
* @param int $x
*/
public function draw( $x ) {
print( $x );
}
}
class ThingAndThat extends That implements Thing {
use ThingBCTrait;
/**
* @param int $x
* @deprecated
*/
public function draw( $x ) {
// We can implement our own BC strategy
$this->draw2d( $x, 12 );
}
public function draw2d( $x, $y ) {
print( "$x:$y" );
}
}
#######################
# We finally remove draw from Thing
# We keep a hard deprecation warning for draw in ThingBCTrait in case some old call sites are still using it
# The Thing interface is now what we expect
# Extensions that want to be compatible with a old MW core version can keep their old draw method.
#######################
/////////////
// Core
/////////////
/**
* Thing that can draw
*/
interface Thing {
/**
* @param int $x
* @param int $y
*/
public function draw2d( $x, $y );
}
/**
* Trait used to ease evolution of the Thing interface
*/
trait ThingBCTrait {
public function draw( $x ) {
wfDeprecated( __METHOD__ . " is deprecated" );
$this->draw2d( $x, 0 );
}
}
/**
* Base class for Thing
*/
abstract class BaseThing implements Thing {
use ThingBCTrait;
}
/////////////
// Extension
/////////////
class SimpleThing extends BaseThing {
/**
* @param int $x
* @param int $y
*/
public function draw2d( $x, $y ) {
print( "$x:$y" );
}
}
class ThingAndThat extends That implements Thing {
use ThingBCTrait;
/**
* @param int $x
* @deprecated
*/
public function draw( $x ) {
// We can implement our own BC strategy
$this->draw2d( $x, 12 );
}
public function draw2d( $x, $y ) {
print( "$x:$y" );
}
}