Framework DSW项目周记1

本文介绍了一种在PHP中实现动态泛型的方法,并通过具体示例展示了如何在类定义及方法调用时动态指定泛型参数,实现了类似Java泛型的功能。

本周实现了一个基于PHP的动态泛型方案。现在PHP可以按照下面的例子来使用泛型了:

<?php
require_once 'FrameworkDSW/System.php';
/**
 * @param <T, P>   <--这里是推荐的phpDoc定义方式
 */
class TChild extends TObject {
    /**
     * @param	T	$p
     */
    public function Func($p) {
        try {
            TType::Type($p, $this->GenericArg('T'));
        }
        catch (EInvalidTypeCasting $e) {
            echo get_class($e) . ' ($p is <div style="border: 1px solid"> ' . var_export($p, true) . '</div>)<br/>';
        }
    }

    /**
     * @param	T	$t
     * @param	P	$p
     */
    public function FuncTwo($t, $p) {
        try {
            TType::Type($t, $this->GenericArg('T'));
        }
        catch (EInvalidTypeCasting $e) {
            echo get_class($e) . ' ($t is <div style="border: 1px solid"> ' . var_export($t, true) . '</div>)<br/>';
        }
        try {
            TType::Type($p, $this->GenericArg('P'));
        }
        catch (EInvalidTypeCasting $e) {
            echo get_class($e) . ' ($p is <div style="border: 1px solid"> ' . var_export($p, true) . '</div>)<br/>';
        }
    }
}
echo '<p>TEST 1</p>';
TChild::PrepareGeneric(array ('T' => 'integer')); //相当于TChild<T: integer>
$obj = new TChild();
$obj->Func(0);
$obj->Func(new TObject()); //此处出错!不是integer
$obj->Func(true); //不出错,因为true是可以转换成1的,根据PHP的==号规则
$obj->Func('string'); //不出错,因为可以转换成0,根据PHP的==号规则

echo '<p>TEST 2</p>';
TChild::PrepareGeneric(array ('T' => 'integer', 'P' => 'TObject'));
$obj = new TChild();
$obj->FuncTwo(0, new TObject());
$obj->FuncTwo(new TObject(), 0); //出错,TObject不是integer,0不是TObject

class TComplex extends TObject {
    /**
     * 
     * @param	T	$t
     */
    public function Func($t) {
        TType::Type($t, $this->GenericArg('T'));
    }
}

echo '<p>TEST 3</p>';
TChild::PrepareGeneric(array ('T' => 'integer', 'P' => 'boolean'));
$c = new TChild();
TComplex::PrepareGeneric(array ('T' => array ('TChild' => array ('T' => 'integer', 'P' => 'boolean'))));
$obj = new TComplex();
$obj->Func($c);
$obj->Func(true);//出错:true不是TChild<T: integer, P: boolean>

注意我们的框架中的泛型是动态泛型。所谓的动态泛型就是在新建对象或者调用静态方法时,可以动态的指定泛型参数,而定义类或者静态方法时不需要指定所需要的泛型参数定义(虽然这个不是好习惯对于我来说,但是保证了PHP的灵活性),也就是说,在Java中需要这样定义和使用:

class Sample<T, P> {
	public static <Q> void Foo(Q param) { /*...*/ }
	public static void main(String[] args) {
		Sample<String, Integer> s = new Sample<String, Integer>(); //类的泛型
		Sample.<Integer>Foo(100); //泛型方法
	}
}

而现在在PHP里面可以这样使用:

/**
 * @param	<T, P>
 */
class TSample extends TObject {
	/**
	 * @param	Q	$param
	 */
	public static function Foo($param) { /*...*/ }
}

TSample::PrepareGeneric(array ('T' => 'string', 'P' => 'integer'));
$s = new TSample();

TSample::PrepareGeneric(array ('X' => 'string', 'Y' => array( 'TSample' => array ('Z' => 'string'))));
$s2 = new TSample();
//动态就在这里体现出来了,现在$s2拥有的泛型参数和$s是完全不同的。
//$s的是<T: string, P: integer>
//$s2的是<X: string, Y: TSample<Z: string>>

TSample::PrepareGeneric(array ('Q' => 'integer'));
TSample::Foo(100);

TSample::PrepareGeneric(array ('P' => 'string'));
TSample::Foo(100);
//这个是方法泛型的动态。

最后,附上相关的API:

void TObject::PrepareGeneric(array $Args)
//为下次创建对象或调用静态方法准备泛型的参数,如果需要的话。
mixed TObject::GenericArgs()
//返回当前对象所有泛型参数的值。
mixed TObject::GenericArg(string $ArgName)
//返回当前对象特定泛型参数名称的泛型参数值。
mixed TObject::StaticGenericArgs()
//返回当前类的泛型参数值,泛型静态方法用。
mixed TObject::StaticGenericArgs(string $ArgName)
//返回当前类的某一泛型参数的值,泛型静态方法用。
boolean TObject::IsInstanceOf(mixed $Type)
//判断当前对象是不是$Type描述的类型。
mixed TObject::ObjectType()
//返回当前对象的类型信息。

void TType::Type(mixed &$Var, mixed $Type)
//确保$Var是$Type类型的变量。
void TType::Obejct(object &$Var, mixed $Type)
//确保$Var是$Type类型的对象。

接下来将要实现的是统一数据库访问接口和对容器框架的泛型化……

转载于:https://www.cnblogs.com/ExSystem/archive/2010/05/01/1725569.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值