1.定义---用于创建对象
2.工厂类型---静态工厂模式(简单工厂)
实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例
常用的场景
例如部署多种数据库时,只需要在配置文件中设定数据库的类型,每次再根据类型生成实例。
所以简单工厂模式一般应用于多种同类型类的情况,将这些类隐藏起来,再提供统一的接口,便于维护和修改。
优点
1.隐藏了对象创建的细节,将产品的实例化推迟到子类中实现。
2.客户端基本不用关心使用的是哪个产品,只需要知道用哪个工厂就行了,提供的类型也可以用比较便于识别的字符串。
3.方便添加新的产品子类,每次只需要修改工厂类传递的类型值就行了。
4.遵循了依赖倒转原则。
缺点
1.要求产品子类的类型差不多,使用的方法名都相同。
2.每添加一个产品子类,都必须在工厂类中添加一个判断分支,这违背了开放-封闭原则。
3.工厂类型---实例工厂模式(工厂方法)
提前定义用于创建对象的接口,让子类决定实例化具体的某一个类,即在工厂和产品中间增加接口,工厂不再负责产品的创建,由接口针对不同条件返回具体的类实例,由具体类实例去实现。
代码如下:
public interface Way {//抽象的产品类--交通工具 void gotowork(); } public class Bike implements Way {//实际的产品类--自行车 @Override public void gotowork() { System.out.println("骑自行车去上班!"); } } public class Bus implements Way {//实际的产品类--公交车 @Override public void gotowork() { System.out.println("坐公交车去上班!"); } }
public interface WayFactory {//抽象的工厂接口 Way getWay(); } public class BikeFactory implements WayFactory {//具体的工厂子类--自行车 @Override public Way getWay() { return new Bike(); } } public class BusFactory implements WayFactory {//具体的工厂子类--公共汽车 @Override public Way getWay() { return new Bus(); } }
public class TestFactory { public static void main(String[] args) { WayFactory factory = null; // bike factory = new BikeFactory(); Way bike = factory.getWay(); bike.gotowork(); // bus factory = new BusFactory(); Way bus = factory.getWay(); bus.gotowork(); } }
优点
基本与简单工厂模式一致,多的一点优点就是遵循了开放-封闭原则,使得模式的灵活性更强。
4.工厂类型---抽象工厂模式
当有多个抽象角色时使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品对象。它有多个抽象产品类,每个抽象产品类可以派生出多个具体产品类,一个抽象工厂类,可以派生出多个具体工厂类,每个具体工厂类可以创建多个具体产品类的实例。
常用的场景
例如Linux和windows两种操作系统下,有2个挂件A和B,他们在Linux和Windows下面的实现方式不同,Factory1负责产生能在Linux下运行的挂件A和B,Factory2负责产生能在Windows下运行的挂件A和B,这样如果系统环境发生变化了,我们只需要修改工厂就行了。
1.封装了产品的创建,使得不需要知道具体是哪种产品,只需要知道是哪个工厂就行了。
2.可以支持不同类型的产品,使得模式灵活性更强。
3.可以非常方便的使用一族中间的不同类型的产品。
缺点
1.结构太过臃肿,如果产品类型比较多,或者产品族类比较多,就会非常难于管理。
2.每次如果添加一组产品,那么所有的工厂类都必须添加一个方法,这样违背了开放-封闭原则。所以一般适用于产品组合产品族变化不大的情况。
工厂模式的优点:
1、一个调用者想创建一个对象,只要知道其名称就可以了,降低了耦合度。
2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。使得代码结构更加清晰。
3、屏蔽产品的具体实现,调用者只关心产品的接口。
工厂模式的缺点:
每次增加一个产品时,都需要增加一个具体类和对象实现工厂(这里可以使用反射机制来避免),使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。所以对于简单对象来说,使用工厂模式反而增加了复杂度。
工厂模式的适用场景:
1, 一个对象拥有很多子类。
2, 创建某个对象时需要进行许多额外的操作。
3, 系统后期需要经常扩展,它把对象实例化的任务交由实现类完成,扩展性好。
总结:
无论是简单工厂模式、工厂模式还是抽象工厂模式,它们本质上都是将不变的部分提取出来,将可变的部分留作接口,以达到最大程度上的复用。究竟用哪种设计模式更适合,这要根据具体的业务需求来决定。