48. public void plant(){
49. log(\ 50. } 51.
52. public static void log(String msg){ 53. System.out.println(msg); 54. } 55.
56. public int getTreeAge(){ 57. return treeAge; 58. } 59.
60. public void setTreeAge(int treeAge){ 61. this.treeAge = treeAge; 62. } 63. }
64. //其他同上.......................... 2、举例: //抽象工厂角色(水果园丁) public interface FruitGardener{ //工厂方法 public Fruit factory(); } //具体工厂类(苹果园丁) public class AppleGardener implements FruitGardener{ public Fruit factory(){ return new Apple(); } } //......(草莓园丁) public class StrawberryGardener implements FuritGardener{ public Fruit factory(){ return new Strawberry(); } } //......(葡萄园丁) public class GrapeGardener implements FuritGardener{ public Fruit factory(){ return new Grape(); } }
//抽象产品角色(水果接口) public interface Fruit{ void grow(); void harvest(); void plant(); } //具体产品角色(苹果类) public class Apple implements Fruit{ private int treeAge; public void grow(){ log(\ } public void harvest(){ log(\ } public void plant(){ log(\ } public static void log(String msg){ System.out.println(msg); } public int getTreeAge(){ return treeAge; } public void setTreeAge(int treeAge){ this.treeAge = treeAge; } } //其他同上..........................
3、工厂方法返还的类型
工厂返还的应当是抽象类型,而不是具体类型,只有这样才能保证整队产品的多态性,调用该工厂方法的客户端可以针对抽象编程,依赖于一个抽象产品类型,而不是具体产品类型。 在特殊情况下,工厂方法仅仅返还一个具体产品类型,这个时候工厂方法模式的功能就退化了,表现为针对产品角色的多态性的丧失,客户端从工厂方法的静态类型可以知道将要得到的是什么类型的对象,而这违背了工厂方法模式的用意
4、与其他模式的关系
1、模板方法模式
工厂方法模式常常与模板方法模式一起联合使用,其原因有二:
一、两个模式都是基于方法的,工厂方法模式是基于多态性的工厂方法的,而模板方法模式是基于模板方法和基于方法的
二、两个模式的哦将具体工作交给子类,工厂方法模式将创建工作推延给子类,模板方法模式将生于逻辑交给子类
2、MVC模式
工厂方法模式总是设计到两个等级结构中的对象,而这两个等级结构可以分别是MVC模式中的控制器和视图。一个MVC模式可以有多个控制器和多个视图,控制器端可以创建合适的视图断,如同工厂角色创建合适的对象角色一样,模型端则可以充当这个创建过程的客户端
3、亨元模式
使用了带有逻辑的工厂方法
4、备忘录模式
亨元模式使用了一个聚集来等级所创建的产品对象,以便可以通过查询这个聚集找到和共享已经创建了的产品对象,这就是备忘录模式的应用
Java代码
1.5、举例:
2. 问题:某一个商业软件产品需要支持Sybase和Oracle数据库。这个系统需要这样一个查询运行期系统,根据客户需要,可以随时向Sybase和Oracle数据库引擎发出查询 3. 答案:可以看出,这个系统是由一个客户端Client,一个抽象工厂角色QueryRunner,两个具体工厂角色SybaseQueryRunner和OracleQueryRunner,以及产品角色组成的
4. 对于客户端Client而言,系统的抽象产品角色是ResultSet接口,而具体产品角色就是java.sql.Connection所返还的具体ResultSet对象,createSql()方法和createConnection()方法实际上也是工厂方法,他们的产品是SQL语句和Connection对象 5. //java抽象类QueryRunner 6. import java.sql.Connection; 7. import java.sql.ResultSet; 8.
9. public abstract class QueryRunner{
10. public ResultSet run() throws Exception{ 11. Connection conn = createConnection(); 12. String sql = createSql(); 13. return runSql(conn,sql); 14. }
15. protected abstract Connection createConnection();
16. protected abstract String createSql();
17. protected abstract ResultSet runSql(Connection conn.String sql)throws Exception; 18. } 19.
20. //具体工厂类
21. import java.sql.Connection; 22. import java.sql.Statement; 23. import java.sql.ResultSet; 24.
25. public class SybaseQueryRunner extends QueryRunner{ 26. public Connection createConnection(){ 27. return null; 28. } 29.
30. protected String createSql(){
31. return \ 32. } 33.
34. protected ResultSet runSql(Connection conn,String sql) throws Exception{ 35. Statement stmt = conn.createStatement(); 36. return stmt.executeQuery(sql); 37. } 38. } 39.
40. //具体工厂类
41. import java.sql.Connection; 42. import java.sql.Statement; 43. import java.sql.ResultSet; 44.
45. public class OracleQueryRunner extends QueryRunner{ 46. public Connection createConnection(){ 47. return null; 48. } 49.
50. protected String createSql(){
51. return \ 52. } 53.
54. protected ResultSet runSql(Connection conn, String sql) throws Exception{ 55. Statement stmt = conn.createStatement(); 56. return stmt.executeQuery(sql); 57. } 58. }
59.
60. //客户端
61. import java.sql.ResultSet; 62.
63. public class Client{
64. private static QueryRunner runner; 65.
66. public static void main(String args[]) throws Exception{ 67. runner = new SybaseQueryRunner(); 68. ResultSet rs = runner.run(); 69. } 70. }
71. 以上给出的答案中,使用了模板方法模式,在QueryRunner中,run()方法就是一个模板方法,这个方法代表一个顶极逻辑:返还产寻的结果ResultSet
《Java与模式》之工厂模式学习
Facotry Pattern包括了三种形态 1. Simple Factory 2. Factory Method 3. Abstract Factory 下面分别进行学习 Simple Factory
简单工厂模式往往是普通工厂模式的一个特例。简单工厂模式基本是用一个类来模拟工厂,通过该工厂类的静态方法返回具体的产品类,而这些产品又源自一个抽象的产品(当然,这儿可能会存在多种抽象产品,即有多种不同类型的产品,如蔬菜、瓜果等等),即静态工厂模式。书中提及了几个对象:水果以及具体的水果,园丁;园丁根据得到的参量来决定提取某种水果。如果存在多种抽象产品,必须考察抽象产品是由抽象类来实现还是用接口来表现了,如果具体产品之间拥有共同的商业逻辑,一般都应用抽象类来表现,否则应用接口来表现,在一个类型的等级结构中,将共同的部分尽量向上塑造。相应的,工厂也可以分为多个工厂,各自负责不同种类的产品即抽象类。
考虑一下,如果我们新增了一种产品,那么在我们的静态工厂类中就必须再加入返回该新增的产品类的方法,是需要修改这个工厂类的。这个到底应该如何才能不修改工厂类呢?或许我们的工厂类不应该同具体产品类来发生关联关系。