天天看点

解读工厂模式Factory Pattern

工厂类就是一个专门用来创建其它对象的类,工厂类在多态性编程实践中是非常重要的。它允许动态替换类,修改配置,会使应用程序更加灵活。掌握工厂模式对Web开发是必不可少的。

工厂模式通常用来返回类似接口的不同的类,工厂的一种常见用法就是创建多态的提供者。

通常工厂模式有一个关键的构造,即一般被命名为factory的静态方法。这个静态方法可以接受任意数量的参数,并且必须返回一个对象。

Program List:基本的工厂类

view source

print?

01

02

<?php

03

class

Fruit {

04

// 对象从工厂类返回

05

}

06

07

Class FruitFactory {

08

09

public

static

function

factory() {

10

// 返回对象的一个新实例

11

return

new

Fruit();

12

}

13

}

14

15

// 调用工厂

16

$instance

= FruitFactory::factory();

17

?>

Program List:利用工厂类生产对象

01

02

<?php

03

class

Example

04

{

05

// The parameterized factory method

06

public

static

function

factory(

$type

)

07

{

08

if

(

include_once

'Drivers/'

.

$type

.

'.php'

) {

09

$classname

=

'Driver_'

.

$type

;

10

return

new

$classname

;

11

}

else

{

12

throw

new

Exception(

'Driver not found'

);

13

}

14

}

15

}

16

17

// Load a MySQL Driver

18

$mysql

= Example::factory(

'MySQL'

);

19

20

// Load an SQLite Driver

21

$sqlite

= Example::factory(

'SQLite'

);

22

?>

Program List:一个完整的工厂类

下面的程序定义了一个通用的工厂类,它生产能够保存你所有操作的空对象,你可以获得一个实例,这些操作都在那个实例中了。

01

<?php

02

03

/**

04

* Generic Factory class

05

*

06

* This Magic Factory will remember all operations you perform on it,

07

* and apply them to the object it instantiates.

08

*

09

*/

10

class

FruitFactory {

11

private

$history

,

$class

,

$constructor_args

;

12

13

/**

14

* Create a factory of given class. Accepts extra arguments to be passed to

15

* class constructor.

16

*/

17

function

__construct(

$class

) {

18

$args

= func_get_args();

19

$this

->

class

=

$class

;

20

$this

->constructor_args =

array_slice

(

$args

, 1 );

21

}

22

23

function

__call(

$method

,

$args

) {

24

$this

->history[] =

array

(

25

'action'

=>

'call'

,

26

'method'

=>

$method

,

27

'args'

=>

$args

28

);

29

}

30

31

function

__set(

$property

,

$value

) {

32

$this

->history[] =

array

(

33

'action'

=>

'set'

,

34

'property'

=>

$property

,

35

'value'

=>

$value

36

);

37

}

38

39

/**

40

* Creates an instance and performs all operations that were done on this MagicFactory

41

*/

42

function

instance() {

43

#

use

Reflection to create a

new

instance, using the

$args

44

$reflection_object

=

new

ReflectionClass(

$this

->

class

); 

45

$object

=

$reflection_object

->newInstanceArgs(

$this

->constructor_args ); 

46

47

# Alternative method that doesn

't use ReflectionClass, but doesn'

t support variable

48

# number of constructor parameters.

49

//$object = new $this->class();

50

51

# Repeat all remembered operations, apply to

new

object.

52

foreach

(

$this

->history

as

$item

) {

53

if

(

$item

[

'action'

] ==

'call'

) {

54

call_user_func_array(

array

(

$object

,

$item

[

'method'

] ),

$item

[

'args'

] );

55

}

56

if

(

$item

[

'action'

] ==

'set'

) {

57

$object

->{

$item

[

'property'

]} =

$item

[

'value'

];

58

}

59

}

60

61

# Done

62

return

$object

;

63

}

64

}

65

66

class

Fruit {

67

private

$name

,

$color

;

68

public

$price

;

69

70

function

__construct(

$name

,

$color

) {

71

$this

->name =

$name

;

72

$this

->color =

$color

;

73

}

74

75

function

setName(

$name

) {

76

$this

->name =

$name

;

77

}

78

79

function

introduce() {

80

print

"Hello, this is an {$this->name} {$this->sirname}, its price is {$this->price} RMB."

;

81

}

82

}

83

84

# Setup a factory

85

$fruit_factory

=

new

FruitFactory(

'Fruit'

,

'Apple'

,

'Gonn'

);

86

$fruit_factory

->setName(

'Apple'

);

87

$fruit_factory

->price = 2;

88

89

# Get an instance

90

$apple

=

$fruit_factory

->instance();

91

$apple

->introduce();

92

93

?>

程序运行结果:

1

Hello, this is an Apple , its price is 2 RMB.

工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。

工厂模式可以分为三类:

  • 简单工厂模式(Simple Factory)
  • 工厂方法模式(Factory Method)
  • 抽象工厂模式(Abstract Factory)

这三种模式从上到下逐步抽象,并且更具一般性。

简单工厂模式又称静态工厂方法模式。重命名上就可以看出这个模式一定很简单。它存在的目的很简单:定义一个用于创建对象的接口。工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承。这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。

工厂方法模式仿佛已经很完美的对对象的创建进行了包装,使得客户程序中仅仅处理抽象产品角色提供的接口。那我们是否一定要在代码中遍布工厂呢?大可不必。也许在下面情况下你可以考虑使用工厂方法模式:

  • 当客户程序不需要知道要使用对象的创建过程。
  • 客户程序使用的对象存在变动的可能,或者根本就不知道使用哪一个具体的对象。

继续阅读