话题引入:
对象的创建和生成
在我们需要创建一个对象时,可以通过各种方式。
最直接的方式莫过于new 了。另外也可以通过Class对象的newInstance(),以及 Constructor.newInstance(Class<?> ... args);进行创建。
1 public class ClassName{ 2 // The defintions of this class goes there. 3 } 4 5 // 通过new 创建 6 ClassName instance = new ClassName(); 7 8 9 // 通过newInstance创建 10 ClassName Instance = Class.forName("...ClassName").newInstance(); 11 ClassName Instance = ClassName.class.getDeclaredConstructor(Class<?> ... args); 12 13 //通过已经存在的对象的clone()方法 14 15 ClassName newInstance = oldInstance.clone(); 16 17 // 通过序列化创建,原理是将当前存在某个对象序列化编程字节码。然后在另外一个地方读取,并构建成对象。 18 19 // 略
另外,当我们进行创建对象的时候,尤其是有用父类引用子类对象的时候,我们都要明确我们确定使用哪个子类的定义和实例化的方式,着无疑加重了开发者的负担:要使用一个东西,还必须要充分了解一个东西,这样是不是很烦呢???
比如说,一个人写了一个类,并且规定了类的很多实例化时的规则,当另一个开发者想使用它的时候,还要去阅读相应的文档………………
这时候我们会抱怨:什么乱七八糟的东西都要我看,都要懂,真烦; 在开发的过程中,我们总希望把我们的注意力放在关键的部分,即业务部分。我们只希望需要哪一个对象的时候,能够很方便的提供给我就行了。嗯,要有一个工厂
就好了,专门造这些东西,造好直接给我就行了。
1.简单工厂模式(Simple Factory Pattern)
举个例子吧,我现在想要一个 iPhone 品牌 的手机 ,现有一个生产手机的的工厂,我们要告诉工厂,“我要一个iPhone” 品牌的手机“。
1 public class Client { 2 public static void main(String[] args) { 3 4 PhoneFactory foxconn = new Foxconn(); 5 Phone iPhone = foxconn.produce("iPhone"); 6 Phone blackBerry= foxconn.produce("BlackBerry"); 7 }
1 //Phone 抽象类 2 class Phone{ 3 //... 4 5 // 打电话 6 public abstract void call(String cardNo); 7 // 上网 8 public abstract void browse(); 9 // 玩游戏 10 public absctract void playGames(); 11 12 } 13 14 // 手机工厂抽象类 15 interface PhoneFactory { 16 public absctract Phone produce(String brand); 17 } 18 19 //iPhone 类 20 public class IPhone implements Phone { 21 22 @Override 23 public void playGames() { 24 System.out.println("Using iphone playing games, so good."); 25 } 26 27 @Override 28 public void browse() { 29 System.out.println("Surfing Internet."); 30 } 31 32 @Override 33 public void call(String number) { 34 System.out.println("Hello,"+number); 35 } 36 } 37 38 39 // BlackBerry l类 40 public class BlackBerry implements Phone{ 41 42 @Override 43 public void call(String number) { 44 45 System.out.println("BlackBerry is calling "+number); 46 } 47 48 @Override 49 public void playGames() { 50 System.out.println("Playing push box..."); 51 } 52 53 @Override 54 public void browse() { 55 56 System.out.println("Browsing the Internet Page."); 57 58 } 59 60 } 61 62 63 // 工厂实现类 64 public class Foxconn implements PhoneFactory{ 65 @Override 66 public Phone produce(String brand) 67 { 68 69 if(brand=="iPhone") 70 { 71 return new IPhone(); 72 } 73 else if (brand == "BlackBerry") 74 { 75 return new BlackBerry(); 76 } 77 else 78 { 79 System.out.println("My factory can't produce it."); 80 } 81 return null; 82 } 83 }
上面的创建的工厂,这就是所谓的 简单工厂模式 (Simple Factory Pattern)。
2. 工厂方法模式(Factory Method Pattern)
随着科技的进步,以后出现了另一款很牛的手机,叫xPhone,我想要一个,这时,着个工厂已经不能满足我了:因为这个工厂不能生产此手机!
想让他给我生产这一款手机,他们工厂就要进行大整改,在 他们的produce(String brand)内部进行修改代码,以支持我的功能。
1 public class Foxconn implements PhoneFactory { 2 @Override 3 public Phone produce(String brand) 4 { 5 6 if(brand=="iPhone") 7 { 8 return new IPhone(); 9 } 10 else if (brand == "BlackBerry") 11 { 12 return new BlackBerry(); 13 } 14 else if (brand == "xPhone") 15 { 16 return new XPhone(); 17 } 18 else 19 { 20 System.out.println("My factory can't produce it."); 21 } 22 return null; 23 } 24 25 }
每次小的需求就令他们做这么大的整改,呵呵,等着倒闭吧。
这里,工厂把所有的实现都放在了一起,可以这么理解,工厂就一个大杂烩,一个作坊;如果我们把这个大杂烩分开,分清每个部门,是功能细化,生产IPhone 的是IPhone部,生产BlackBerry 的是BlackBerry部,他们部门互不影响,如果要新生产一款手机 xPhone, 则可以在不影响当前其他部门的情况下,新增一个 xPhone部门专门负责 。
我们开发出来的东西,要力争在结构上作尽量小的整改,增加其拓展性。当前的这个工厂,我们把所有的处理和逻辑全部交给了produce() 方法,所以每次有新的需求都要进行更改,破坏其结构,所以,我们尝试把这个方法的功能分开,工厂变为下面的结构:
1 // 功能分开和细化,相互之间无影响 2 public interface PhoneFactory{ 3 public abstract Phone produceIPhone(); 4 public abstract Phone produceBlackBerry(); 5 } 6 7 public class Foxconn implements PhoneFactory{ 8 9 @Override 10 public Phone produceIPhone() { 11 return new IPhone(); 12 } 13 14 @Override 15 public Phone produceBlackBerry() { 16 return new BlackBerry(); 17 } 18 19 }
现在我们 在现有工厂的基础上,增加一个XPhone部门:
1 // 新增一个部门生产 XPhone 2 public interface Phone1Factory extends PhoneFactory { 3 public abstract Phone produceXPhone(); 4 } 5 6 // 工厂实现类 7 public class Foxconn1 extends Foxconn implements Phone1Factory{ 8 9 @Override 10 public Phone produceXPhone(){ 11 return new XPhone(); 12 } 13 14 }
这样,在不破坏以前代码结构的基础上,都当前代码进行扩展。
也就是说,当有新的要求提出时,我们通过给工厂增加部门的形式给出(即这里的方法),这种拓展性非常好!
上面的描述便是 工厂方法模式(Factory Method Pattern)。
工厂方法模式 扩展性非常好,但是拓展性带来了一个新的问题,拓展性增加了我们系统里类的数量和规模,这使我们的系统异常庞大!
只要有新的生产要求提出,都会有新的方法添加。就好比 每让一个工厂给你新类型的产品,就得新建一个新的部门予以支持,这样的代价也是相当大的。
3. 抽象工厂模式
举个实际的例子,IPhone 现在 5S 刚出来,我现在要工厂给我造出来,那工厂自然提供一个部门给我造,那以后IPhone 的后续还会推出各种新的 款式.....我们发现,IPhone 是一个系列,无论它是几S 终究是IPhone ,我们可以告诉IPhone的部门,我们要几S就够了,这样子 便可以减少我们部门的规模了!
现在我们对 上述的类进行整改:
1 // Phone工厂抽象类 2 public interface PhoneFactory { 3 public abstract Phone produceIPhone(String version); 4 public abstract Phone produceBlackBerry(String version); 5 } 6 7 class Foxconn implements PhoneFactory { 8 9 @Override 10 public Phone produceIPhone(String version) { 11 if(version.equals("4")) 12 { 13 return new IPhone4(); 14 } 15 else if(version.equals("4S")) 16 { 17 return new IPhone4S(); 18 } 19 else 20 { 21 //........ 22 } 23 24 } 25 26 @Override 27 public Phone produceBlackBerry(String version) { 28 // TODO Auto-generated method stub 29 return null; 30 } 31 } 32 33 // Phone工厂抽象类 34 public interface Phone1Factory extends PhoneFactory { 35 public abstract Phone produceXPhone(String version); 37 } 38 39 class Foxconn1 extends Foxconn implements PhoneFactory { 40 41 @Override 42 public Phone produceXPhone(String version) { 43 if(version.equals("X1")) 44 { 45 return new XPhoneX1(); 46 } 47 else if(version.equals("X2")) 48 { 49 return new XPhoneX2(); 50 } 51 else 52 { 53 //........ 54 } 55 56 } 57 }
这样的方式便是扩展性和规模和复杂度的一个中和。