而客户端则可以免除直接创建产品对象的责任,而仅仅负责“消费”产品。简单工厂模式通过这种做法实现了对责任的分割
缺点:1)这个工厂类集中了所有的产品创建逻辑,形成一个无所不知的全能类,有人把这种类叫做上帝类(God Class)。
如果这个全能类代表的是农场的一个具体园丁的话,那么这个园丁就需要对所有的产品负责,成了农场的关键人物,
他什么时候不能正常工作了,整个农场都要受到影响;
2)将这么多的逻辑集中放在一个类里面的另外一个缺点是,当产品类有不同的接口种类时,工厂需要判断在什么时候创建某种产品,
这种对时机的判断和对哪一种具体产品的判断逻辑混合在一起,使得系统在将来进行功能扩展时较为困难。
这一缺点在工厂方法模式中得到克服
3)由于简单工厂模式使用静态方法作为工厂反尬,而静态方法无法由子类继承,因此工厂角色无法形成基于继承的等级结构。
这一缺点会在工厂方法模式中得到克服 7、“开——闭”原则要求一个系统的设计能够允许系统在无需修改的情况下,扩展其功能。 要求系统允许当新的产品加入系统中时,而无需对现有代码进行修改,这一点对于产品消费者角色是成立的,而对于工厂角色是不成立的
一般而言:一个系统总是可以划分成为产品的消费者角色(Client)、产品的工厂角色(Factory)以及产品角色(Product)三个子系统 对于产品消费者角色来说,任何时候需要某种产品,只需向工厂角色请求即可,而工厂角色在接到请求后,
会自行判断创建和提供哪一个产品,所以,产品消费者角色无需知道它得到的是哪一个产品,
产品消费者角色无需修改就可以接纳新的产品,而接纳新的产品意味着要修改这个工厂角色的源代码
(简单工厂角色只在有限的程度上支持“开—闭”原则)
工厂方法(Factory Method)模式:
1、工厂方法模式是类的创建模式,又叫做虚拟构造子模式或者多态性工厂模式
工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。
一般而言工厂方法模式的系统设计到以下几种角色:
1) 抽象工厂(Creator)角色:担任这个角色的是工厂方法模式的核心,它是与应用程序无关的,
任何在模式之中个窗对象的工厂类必须实现这个接口,在实际系统中,这个角色也使用抽象类实现
2) 具体工厂(Concrete Creator)角色:担任这个角色的是实现了抽象工厂接口的具体java类。
具体工厂角色含有与用应密切相关的逻辑,并且受到应用程序的调用以创建产品对象。
3) 抽象产品角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口,
在实际应用中,这个角色也常常使用抽象java类实现
4) 具体产品角色:这个角色实现了抽象产品角色所声明的接口。工厂方法模式所创建的每一个对象都是某个具体产品角色的实例
Java代码
1.2、举例:
2. //抽象工厂(角色)接口 3. public interface Creator{ 4. //工厂方法
5. public Product factory(); 6. } 7.
8. //抽象产品(角色)接口 9. public interface Product{ 10.
11. } //一个没有声明任何方法的接口叫做标识接口 12.
13. //具体工厂(角色)类
14. public class ConcreteCreator1 implements Creator{ 15. //工厂方法
16. public Product factory(){
17. return new ConcreteProduct1(); 18. } 19. } 20.
21. public class ConcreteCreator2 implements Creator{ 22. //工厂方法
23. public Product factory(){
24. return new ConcreteProduct2(); 25. } 26. } 27.
28. //具体产品(角色)类
29. public class ConcreteProduct1 implements Product{ 30. public ConcreteProduct1(){ 31. //do somthing 32. } 33. } 34.
35. public class ConcreteProduct2 implements Product{ 36. public ConcreteProduct2(){ 37. //do somthing 38. } 39. } 40.
41. //客户端(角色)类 42. public class Client{
43. private static Creator creator1,creator2; 44. private static Product prod1,prod2; 45.
46. public static void main(String args[]){ 47. creator1 = new ConcreteCreator1(); 48. prod1 = creator1.factory();
49. creator2 = new ConcreteCreator2(); 50. prod2 = creator2.factory(); 51. } 52. } 2、举例: //抽象工厂(角色)接口 public interface Creator{ //工厂方法 public Product factory(); } //抽象产品(角色)接口 public interface Product{ } //一个没有声明任何方法的接口叫做标识接口 //具体工厂(角色)类 public class ConcreteCreator1 implements Creator{ //工厂方法 public Product factory(){ return new ConcreteProduct1(); } }
public class ConcreteCreator2 implements Creator{ //工厂方法 public Product factory(){ return new ConcreteProduct2(); } } //具体产品(角色)类 public class ConcreteProduct1 implements Product{ public ConcreteProduct1(){ //do somthing } } public class ConcreteProduct2 implements Product{ public ConcreteProduct2(){ //do somthing } } //客户端(角色)类 public class Client{ private static Creator creator1,creator2; private static Product prod1,prod2; public static void main(String args[]){ creator1 = new ConcreteCreator1(); prod1 = creator1.factory(); creator2 = new ConcreteCreator2(); prod2 = creator2.factory(); } }
Client对象的活动可以分为两部分
1) 客户端创建 ConcreteCreator1 对象,这时客户端所持有变量的静态类型是Creator,而实际类型是 ConcreteCreator1,然后,客户端调用 ConcreteCreator1 对象的工厂方法 factory() ,接着后者调用 ConcreteProduct1 的构造子创建出产品对象
Java代码
1.2、举例:
2. //抽象工厂角色(水果园丁) 3. public interface FruitGardener{
4. //工厂方法
5. public Fruit factory(); 6. } 7.
8. //具体工厂类(苹果园丁)
9. public class AppleGardener implements FruitGardener{ 10. public Fruit factory(){ 11. return new Apple(); 12. } 13. } 14.
15. //......(草莓园丁)
16. public class StrawberryGardener implements FuritGardener{ 17. public Fruit factory(){
18. return new Strawberry(); 19. } 20. } 21.
22. //......(葡萄园丁)
23. public class GrapeGardener implements FuritGardener{ 24. public Fruit factory(){ 25. return new Grape(); 26. } 27. } 28.
29. //抽象产品角色(水果接口) 30. public interface Fruit{ 31. void grow(); 32. void harvest(); 33. void plant(); 34. } 35.
36. //具体产品角色(苹果类)
37. public class Apple implements Fruit{ 38. private int treeAge; 39.
40. public void grow(){
41. log(\ 42. } 43.
44. public void harvest(){
45. log(\ 46. } 47.