为什么使用工厂方法?
Duck duck=new MallardDuck();//使用接口让代码更具有弹性//但是还是建立了具体类的实例
在有一群相关类时,当场会写出这样的代码
Duck duck;if(picnic){ duck=new MallarDuck();}if(hunting){ duck=new DecoyDuck();}else if(inBathTub){ duck=new RubberDuck();}
在很多情况下,我们究竟要实例化哪个具体类,要在运行时有一些条件来决定。当看到这样的代码,一旦有变化或者扩展,就必须重新打开这段代码进行检查修改。通常这样修改过的代码将早场部分系统更难维护和更新,而且也更容易犯错。
直接使用new不符合“对修改关闭”的原则,我们应该依据“找出会变化的原则,把它们从不变的部分分离出来”的原则写代码。
解决方案:
什么是工厂方法?
工厂方法模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定特定类。
原则:依赖抽象,不要依赖具体类。
目的:为了得到更松的耦合,更有弹性的设计。
简单的理解:
实例 -> 类 -> 类工厂
实例 -> 类 -> 类工厂 -> 抽象工厂
工厂方法是个方法,是在提供的抽象接口中,用来创建“一个产品”的方法。
createPizza();
然后具体子类,通过实现此接口来实现这个createPizze()的具体方法。
抽象工厂是个接口,在接口中,创建“很多产品”(或者说一个产品家族,因为产品之间有一定的联系)。
createDough();createSauce();createCheese();//多个产品,但是相互之间有联系,都是一种披萨的配料
然后具体子类,通过实现此接口来实现创建这个产品家族,而其中每一个create方法,都可以使用工厂方法来实现。
可以说抽象工厂的实现中,运用到了工厂方法。
换句话说:抽象工厂的任务是定义一个负责创建一组产品的接口,这个接口内的每一个方法都负责创建一个具体产品,同时我们利用实现抽象工厂的子类来提供这些具体的算法。所以,在抽象工厂中利用工厂方法实现生产方法是相当自然的做法。