为了更好地阐述工厂模式,我们先定义好后续使用的实体类。我们定义一个Mouse接口,包含info()简介鼠标的信息:
1 | public interface Mouse { |
接下来创建两个实现Mouse接口的实体类:
1 | public class HpMouse implements Mouse { |
1 | public class LenovoMouse implements Mouse { |
简单工厂模式
简单工厂模式使用一个工厂类来管理对象的创建。工厂类提供一个静态的方法,通过方法传参的不同,返回不同的对象。
1 | /** |
创建对象时,使用如下:
1 | Mouse hp = MouseFactory.createMouse("Hp"); |
通过这种简单工厂模式,隐藏了对象的创建细节,统一在工厂类中管理对象的创建。但是它的缺点也很明显,一旦需要增加新的实现类,就需要修改MouseFactory类,这违反了开闭原则。
有没有什么方法可以不违反开闭原则吗?
工厂方法模式
工厂方法模式定义一个用于创建对象的接口,让子类决定实例化哪一个类。同简单工厂相比,工厂方法模式需要多定义一个接口:
1 | public interface MouseFactory { |
每一个对象对应于一个生产对象的工厂类。
1 | public class HpMouseFactory implements MouseFactory { |
1 | public class LenovoMouseFactory implements MouseFactory { |
创建对象时,使用如下:
1 | HpMouseFactory hpMouseFactory = new HpMouseFactory(); |
工厂方法模式同样也隐藏了对象的创建细节,对比于简单工厂模式,它并没有违反开闭原则,反而实现了单一责则。
其一缺点是只支持同一类产品的创建,因为MouseFactory规定了只创建Mouse的对象。
其二每增加一个实体类,都需要增加对应的工厂类,比较繁琐。
抽象工厂模式
抽象工厂模式适用于创建同一产品族的对象。也需要定义接口:
1 | public interface ComputerFactory { |
创建接口的实现类:
1 | public class HpComputerFactory implements ComputerFactory { |
1 | public class LenovoComputerFactory implements ComputerFactory { |
抽象工厂模式和工厂方法很类似,区别在于抽象工厂模式是对同一产品族对象的创建,而工厂方法是对同一产品对象的创建。
抽象工厂模式同样违反了开闭原则,当ComputerFactory方法新增加一个方法时,其实现类都需要实现这个方法。