本文共 4715 字,大约阅读时间需要 15 分钟。
工厂模式属于23种设计模式之一,属于创建性设计模式。在许多优秀的框架的源码中都有过应用。
工厂模式可以分为三大类:简单工厂模式、工厂方法模式、抽象工厂模式
定义:指由一个工厂对象决定创建出哪一种产品类的实例。
简单工厂适用于工厂类负责创建的对象较少的场景,且客户端只需要传入工厂类的参数,对于如何创建对象的逻辑不需要关心。
我们举一个例子:华为公司是一家大型企业,既生产手机又生产电脑等科技产品,我们可以定义一个华为产品的接口 IHWProduct:
public interface IHWProduct { void produce();}
创建一个华为手机类,实现 **IHWProduct **接口:
public class HWMobile implements IHWProduct { public void produce() { System.out.println("生产华为手机"); }}
创建一个华为电脑类,实现 **IHWProduct **接口:
public class HWComputer implements IHWProduct { public void produce() { System.out.println("生产华为电脑"); }}
此时我们创建一个华为工厂类,并提供一个生产产品的方法:
public class HWFactory { public static IHWProduct create(@NotNull String name) { IHWProduct huawei = null; if ("computer".equals(name)) { huawei = new HWComputer(); } else if ("mobile".equals(name)) { huawei = new HWMobile(); } return huawei; }}
当我们在使用客户端想要售卖华为手机的时候,代码如下:
public class Test { public static void main(String[] args) { IHWProduct mobile = HWFactory.create("mobile"); mobile.produce(); }}
从上面的代码中,我们不难看出,如果我们的业务继续扩展,那么工厂中的create()方法也要根据产品的增加而修改代码逻辑,这样显然是不符合开闭原则的。
我们可以使用反射技术来优化上面的工厂方法:
public class HWFactory { public static IHWProduct create(Class clazz) { IHWProduct huaWei = null; try { huaWei = (IHWProduct) clazz.newInstance(); } catch (Exception e) { e.printStackTrace(); } return huaWei; }}
修改客户端使用的代码:
public static void main(String[] args) { IHWProduct ihwProduct = HWFactory.create(HWComputer.class); ihwProduct.produce(); }
代码优化过后,就算产品继续增加,也不需要修改工厂的create()方法了。
优点:只需要传入一个正确的参数,就可以获取你所需要的对象,并不需要知道其创建的细节
缺点:工厂类的职责过重,不易于扩展过于复杂的产品结构
定义:定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类进行。在工厂方法 模式中用户只需要关心所需产品对应的工厂,无须关心创建细节,而且加入新的产品符合开闭原则。
工厂方法模式主要解决产品扩展的问题,在简单工厂中,随着产品链的丰富,如果每个产品的创建逻辑有区别的话,工厂的职责会变得越来越多,有点像万能工厂,并不便于维护。根据单一职责原则我们将职能继续拆分,专人干专事。华为手机由 华为手机工厂创建, 华为电脑由华为电脑 工厂创建,对工厂本身也做一个抽象。来看代码,先创建 IHWFactory 接口:
public interface IHWFactory { IHWProduct create();}
再分别创建华为手机工厂类和华为电脑工厂类,分别实现 IHWFactory 接口:
public class HWComputerFactory implements IHWFactory { public IHWProduct create() { return new HWComputer(); }}public class HWMobileFactory implements IHWFactory { public IHWProduct create() { return new HWMobile(); }}
看测试方法:
public class Test { public static void main(String[] args) { IHWFactory ihwComFactory = new HWComputerFactory(); IHWProduct hwComputer = ihwComFactory.create(); hwComputer.produce(); IHWFactory ihwMobFactory = new HWMobileFactory(); IHWProduct hwMobile = ihwMobFactory.create(); hwMobile.produce(); }}
工厂方法适用于以下场景:
工厂方法也有缺点:
定义:提供一个创建一系列相关或者相互依赖的接口的对象,无须指定她们具体的类。
什么意思呢?我们举个栗子:像类似华为公司这样既生产手机又生产电脑的公司就有很多,比如说苹果和小米。
这三个公司的性质相同或者相似,都能生产相同的产品,只不过产品的品牌不一样。所以我们定义一个抽象工厂类 CompanyFactory以及所能生产的产品接口IComputer 、IMobile:
public interface CompanyFactory { IComputer createComputer(); IMobile createMobile();}
public interface IComputer { void produce();}public interface IMobile { void produce();}
接着我们创建华为生产手机和电脑以及苹果生产手机和电脑的具体实现类:
public class HWComputer implements IComputer { public void produce() { System.out.println("生产华为电脑"); }}public class HWMobile implements IMobile { public void produce() { System.out.println("生产华为手机"); }}public class Appleomputer implements IComputer { public void produce() { System.out.println("生产苹果电脑"); }}public class AppleMobile implements IMobile { public void produce() { System.out.println("生产苹果手机"); }}
那么每个公司生产产品的方法都有了,就可以建立工厂开始生成了:
public class HWFactory implements CompanyFactory { public IComputer createComputer() { return new HWComputer(); } public IMobile createMobile() { return new HWMobile(); }}public class AppleFactory implements CompanyFactory { public IComputer createComputer() { return new Appleomputer(); } public IMobile createMobile() { return new AppleMobile(); } }
现在我们要生成苹果的手机和电脑,来看下客户端的调用:
public class Test { public static void main(String[] args) { CompanyFactory appleFactory = new AppleFactory(); IComputer mbp = appleFactory.createComputer(); IMobile iphone = appleFactory.createMobile(); mbp.produce(); iphone.produce(); }}
抽象工厂的缺点:
转载地址:http://tqmbi.baihongyu.com/