天天看點

解讀工廠模式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)

這三種模式從上到下逐漸抽象,并且更具一般性。

簡單工廠模式又稱靜态工廠方法模式。重命名上就可以看出這個模式一定很簡單。它存在的目的很簡單:定義一個用于建立對象的接口。工廠方法模式去掉了簡單工廠模式中工廠方法的靜态屬性,使得它可以被子類繼承。這樣在簡單工廠模式裡集中在工廠方法上的壓力可以由工廠方法模式裡不同的工廠子類來分擔。

工廠方法模式仿佛已經很完美的對對象的建立進行了包裝,使得客戶程式中僅僅處理抽象産品角色提供的接口。那我們是否一定要在代碼中遍布工廠呢?大可不必。也許在下面情況下你可以考慮使用工廠方法模式:

  • 當客戶程式不需要知道要使用對象的建立過程。
  • 客戶程式使用的對象存在變動的可能,或者根本就不知道使用哪一個具體的對象。

繼續閱讀