将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦。从而提升项目的扩展和维护性。工厂模式都是实现建立者和调用者分离,下面开始逐一介绍:程序员
工厂角色(Creator) | 是简单工厂模式的核心,它负责实现建立全部具体产品类的实例。工厂类能够被外界直接调用,建立所需的产品对象。 |
抽象产品角色(Product) | 是全部具体产品角色的父类,它负责描述全部实例所共有的公共接 口 。 |
具体产品角色(Concrete Product) | 继承自抽象产品角色,通常为多个,是简单工厂模式的建立目标。工厂类返回的都是该角色的某一具体产品。 |
package Factory; interface Car{ void run(); } class Aodi implements Car{ @Override public void run() { System.out.println("我是奥迪汽车..."); } } class Benchi implements Car{ @Override public void run() { System.out.println("我是奔驰汽车..."); } } class CarFactory{ static public Car createCar(String name) { Car car = null; if(name.equals("奥迪")) { car = new Aodi(); }else if(name.equals("奔驰")) { car = new Benchi(); } return car; } } /** * @author Moti * @Time 2019年9月21日 */ public class Main { public static void main(String[] args) { Car car = CarFactory.createCar("奔驰"); car.run(); } }
工厂类是整个模式的关键.包含了必要的逻辑判断,根据外界给定的信息,决定究竟应该建立哪一个具体类的对象.经过使用工厂类,外界能够从直接建立具体产品对象的尴尬局面摆脱出来,仅仅须要负责“消费”对象就能够了。而没必要管这些对象究竟如何建立及如何组织的.明确了各自的职责和权利,有利于整个软件体系结构的优化。ide
因为工厂类集中了全部实例的建立逻辑,违反了高内聚责任分配原则,将所有建立逻辑集中到了一个工厂类中;它所能建立的类只能是事先考虑到的,若是须要添加新的类,则就须要改变工厂类了。违反开闭原则 。性能
当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不一样条件建立不一样实例的需求.这种对条件的判断和对具体产品类型的判断交错在一块儿,很难避免模块功能的蔓延,对系统的维护和扩展很是不利;优化
这些缺点在工厂方法模式中获得了必定的克服。this
每个产品都有本身独立的工厂设计
抽象产品(Product) | 具体产品的父类 描述具体产品的公共接口 |
具体产品(Concrete Product) | 抽象产品的子类;工厂类建立的目标类 描述生产的具体产品 |
抽象工厂(Factory) | 具体工厂的父类 描述具体工厂的公共接口 |
具体工厂(Concrete Factory) | 抽象工厂的子类;被外界调用描述具体工厂;实现FactoryMethod工厂方法建立产品的实例 |
1. 汽车的抽象类3d
package AbstractFactory; /** * 定义汽车的抽象类 * @author Moti * @Time 2019年9月27日 下午3:04:23 */ public abstract class Car { public abstract void run(); }
2. 奥迪汽车类code
package AbstractFactory; /** * 定义奥迪车,继承抽象类Car实现run方法 * @author Moti * @Time 2019年9月27日 下午3:06:10 */ public class Aodi extends Car { @Override public void run() { System.out.println("我是奥迪车..滴滴滴.."); } }
3. 奔驰汽车类对象
package AbstractFactory; /** * 定义奔驰车,继承抽象类Car实现run方法 * @author Moti * @Time 2019年9月27日 下午3:07:29 */ public class Benchi extends Car { @Override public void run() { System.out.println("我是奔驰车..滴滴滴.."); } }
4. 抽象汽车工厂的接口blog
package AbstractFactory; /** * 汽车工厂的接口,将具体实例的生成交给子类 * @author Moti * @Time 2019年9月27日 下午3:08:35 */ public interface CarFactory { Car createCar(); }
5. 奥迪汽车工厂的类,实现了抽象汽车工厂接口
package AbstractFactory; /** * 定义奥迪车的工厂 * @author Moti * @Time 2019年9月27日 下午3:09:53 */ public class AodiCarFactory implements CarFactory { @Override public Car createCar() { return new Aodi(); } }
6. 奔驰汽车工厂的类,实现了抽象汽车工厂接口
package AbstractFactory; /** * 定义奔驰车的工厂 * @author Moti * @Time 2019年9月27日 下午3:10:57 */ public class BenchiCarFactory implements CarFactory { @Override public Car createCar() { return new Benchi(); } }
7. 客户端调用
package AbstractFactory; /** * @author Moti * @Time 2019年9月27日 下午3:12:45 */ public class Client { public static void main(String[] args) { CarFactory carFactory1 = new AodiCarFactory(); CarFactory carFactory2 = new BenchiCarFactory(); Car car1 = carFactory1.createCar(); Car car2 = carFactory2.createCar(); car1.run(); car2.run(); } }
用户只须要关心所需产品对应的工厂,无需关心建立细节,甚至无需知道具体产品类名;全部的具体工厂类都具备同一抽象父类;符合开闭原则,新增产品只须要添加工厂类和具体产品,无需修改代码,扩展性好;
添加一个新的产品,系统中类的个数增长,致使增长了系统的复杂性,有更多的类须要编译和运行,会增长系统性能的开销;因为考虑到系统的可扩展性,须要引入抽象层,在客户端代码中均使用抽象层进行定义,增长了系统的抽象性和理解难度;
产品等级:产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。
产品族:在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不一样产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中,海尔电视机、海尔电冰箱构成了一个产品族。
这里,1号工厂(ConcreteFactory1)能够生产A,B,C三种产品(ConcreteProductA,B,C)
一样,2号工厂也能够生产A,B,C三种产品
那么1号工厂生产的这三种产品构成一个产品族,2号工厂生产的这三种产品也构成一个产品族.
1号工厂生产的A产品和2号工厂生产的A产品构成一个产品等级
1号工厂生产的B产品和2号工厂生产的B产品 构成一个产品等级
1号工厂生产的C产品和2号工厂生产的C产品 构成一个产品等级
抽象产品(Product) | 具体产品的父类 描述具体产品的公共接口 |
具体产品(Concrete Product) | 抽象产品的子类;工厂类建立的目标类 描述生产的具体产品 |
抽象工厂(Factory) | 具体工厂的父类 描述具体工厂的公共接口 |
具体工厂(Concrete Factory) | 抽象工厂的子类;被外界调用描述具体工厂;实现抽象工厂中建立产品的实例 |
注意:这里日本工厂生产的全部产品构成一个产品族,中国工厂生产的全部产品也构成一个产品族,共两个产品族.示例程序中出现了两种RAM,两种CPU,两种Mouse(分别来自中国工厂和日本工厂),这些同种商品分类构成一个产品等级,也就是说有三个产品等级.
1.抽象产品和具体产品
//设备接口(产品的抽象) public interface Device { String getDeviceName(); } //RAM(具体的产品) public class RAM implements Device { private String factoryName; public RAM(String factoryName) { this.factoryName = factoryName; } @Override public String getDeviceName() { return "得到"+factoryName+"生产的RAM"; } } //CPU(具体的产品) public class CPU implements Device { private String factoryName; public CPU(String factoryName) { this.factoryName = factoryName; } @Override public String getDeviceName() { return "得到"+factoryName+"生产的CPU"; } } //Mouse(具体的产品) public class Mouse implements Device { private String factoryName; public Mouse(String factoryName) { this.factoryName = factoryName; } @Override public String getDeviceName() { return "得到"+factoryName+"生产的Mouse"; } }
2.抽象工厂和具体工厂
//抽象工厂 public interface DeviceFactory { Device createCPU(); Device createARM(); Device createMouse(); } //具体工厂 public class ChinaFactoy implements DeviceFactory { @Override public Device createCPU() { return new CPU("中国"); } @Override public Device createARM() { return new RAM("中国"); } @Override public Device createMouse() { return new Mouse("中国"); } } //具体工厂 public class JapanFactory implements DeviceFactory{ @Override public Device createCPU() { return new CPU("日本"); } @Override public Device createARM() { return new RAM("日本"); } @Override public Device createMouse() { return new Mouse("日本"); } }
3.客户端Client
public class Client { public static void main(String[] args) { DeviceFactory factory = new JapanFactory(); Device device = factory.createMouse(); String string = device.getDeviceName(); System.out.println(string); } }
分离了具体的类。客户经过抽象接口操纵实例,产品的类名也在具体工厂的实现中被分离,它们不出如今客户代码中。
易于交换产品系列。一个具体工厂类只在初始化时出现一次,这使得改变一个应用的具体工厂变得很容易,只需改变具体的工厂便可使用不一样的产品配置。
有利于产品的一致性。当一个系列的产品对象被设计成一块儿工做时,一个应用一次只能使用同一个系列中的对象,这一点很重要,而抽象工厂很容易实现这一点。
难以支持新种类的产品。由于抽象工厂接口肯定了能够被建立的产品集合(产品族),因此难以扩展抽象工厂以生产新种类的产品。