工厂模式
1:工厂方法模式:
1)生产4种产品,华为手机、华为汽车、小米手机、小米汽车,每个产品都要有对应的工厂来生产
2)优点:符合开闭原则,当新增一个产品的时候,就新增一个产品类和对应的工厂类,不会对原来的这8个类产生影响
3)缺点:每增加一个产品,就会多一个对应的产品类和其对应的工厂类,容易类爆炸。解决方案:抽象工厂模式
public class FactoryTest { //定义抽象产品类 public interface Phone { String phoneName(); } //定义具体实现类 public class Mate60 implements Phone { @Override public String phoneName() { return "my name is Mate60"; } } //定义具体实现类 public class Xiaomi11 implements Phone { @Override public String phoneName() { return "my name is Xiaomi11"; } } //定义抽象工厂 public interface PhoneFactory { Phone generatePhone(); } //定义Huawei工厂,生成华为手机 public class HuaweiPhoneFactory implements PhoneFactory { @Override public Phone generatePhone() { return new Mate60(); } } //定义Xiaomi工厂,生成小米手机 public class XiaomiPhoneFactory implements PhoneFactory { @Override public Phone generatePhone() { return new Xiaomi11(); } } public interface Car { String carName(); } public class XiaomiCar implements Car { @Override public String carName() { return "my name is XiaomiCar"; } } public class HuaweiCar implements Car { @Override public String carName() { return "my name is HuaweiCar"; } } public interface CarFactory { Car generateCar(); } public class XiaomiCardFactory implements CarFactory { @Override public Car generateCar() { return new XiaomiCar(); } } public class HuaweiCarFactory implements CarFactory { @Override public Car generateCar() { return new HuaweiCar(); } } //使用: public void test() { //生产华为手机 PhoneFactory huaweiFactory = new HuaweiPhoneFactory(); Phone mate60 = huaweiFactory.generatePhone(); Log.d("test", "Huawei phone name--->" + mate60.phoneName()); //生产小米手机 PhoneFactory xiaomiFactory = new XiaomiPhoneFactory(); Phone xiaomi11 = xiaomiFactory.generatePhone(); Log.d("test", "Xiaomi phone name--->" + xiaomi11.phoneName()); //生产华为汽车 CarFactory huaweiCarFactory = new HuaweiCarFactory(); Car huaweiCar = huaweiCarFactory.generateCar(); Log.d("test", "huaweiCar name--->" + huaweiCar.carName()); //生产小米汽车 CarFactory XiaoCarFactory = new XiaomiCardFactory(); Car xiaomiCar = XiaoCarFactory.generateCar(); Log.d("test", "xiaomiCar name--->" + xiaomiCar.carName()); } }
加上反射的用法,可以优化:
public class FactoryTest { //定义抽象产品类 public abstract class Phone { public abstract String brandName(); } //定义具体实现类 public class Huawei extends Phone { @Override public String brandName() { return "my name is Huawei"; } } //定义具体实现类 public class Xiaomi extends Phone { @Override public String brandName() { return "my name is Xiaomi"; } } //定义抽象工厂 public abstract class Factory { public abstract <T extends Phone> T generatePhone(Class<T> tClass); } //具体工厂 public class ConcretFactory extends Factory { @Override public <T extends Phone> T generatePhone(Class<T> tClass) { Phone phone = null; try { phone = (Phone) Class.forName(tClass.getName()).newInstance(); Log.e("test", "生产了一个手机"); phone.brandName(); } catch (Exception e) { } return (T) phone; } } //使用: public void test() { Phone huaweiPhone = new ConcretFactory().generatePhone(Huawei.class); huaweiPhone.brandName(); } }
2:抽象工厂:一个工厂不满足于生产一个产品,而是一个产品族。我们可以把以上的产品按照厂家分为两类,华为和小米,那我们只需要两个工厂就行了
华为工厂生产华为手机和汽车,小米工厂生成小米手机和汽车
把HuaweiCarFactory和HuaweiPhoneFactory抽象合并成HuaweiFactory,这个工厂可以生产华为汽车和手机两个产品
把XiaomiCarFactory和XiaomiPhoneFactory抽象合并成XiaomiFactory,这个工厂可以生产小米汽车和手机两个产品
所以说抽象工厂是工厂的抽象。
public class FactoryTest { //定义抽象产品类 public interface Phone { String phoneName(); } //定义具体实现类 public class Mate60 implements Phone { @Override public String phoneName() { return "my name is Mate60"; } } //定义具体实现类 public class Xiaomi11 implements Phone { @Override public String phoneName() { return "my name is Xiaomi11"; } } //定义抽象工厂 public interface Factory { Phone generatePhone(); Car generateCar(); } //定义Huawei工厂,生成华为手机 public class HuaweiFactory implements Factory { @Override public Phone generatePhone() { return new Mate60(); } @Override public Car generateCar() { return new HuaweiCar(); } } //定义Xiaomi工厂,生成小米手机 public class XiaomiFactory implements Factory { @Override public Phone generatePhone() { return new Xiaomi11(); } @Override public Car generateCar() { return new XiaomiCar(); } } public interface Car { String carName(); } public class XiaomiCar implements Car { @Override public String carName() { return "my name is XiaomiCar"; } } public class HuaweiCar implements Car { @Override public String carName() { return "my name is HuaweiCar"; } } //使用: public void test() { //生产华为手机 Factory huaweiFactory = new HuaweiFactory(); //生产华为汽车 Phone mate60 = huaweiFactory.generatePhone(); Car huaweiCar = huaweiFactory.generateCar(); Log.d("test", "Huawei phone name--->" + mate60.phoneName()); Log.d("test", "huaweiCar name--->" + huaweiCar.carName()); //生产小米手机 Factory xiaomiFactory = new XiaomiFactory(); //生产小米汽车 Phone xiaomi11 = xiaomiFactory.generatePhone(); Car xiaomiCar = xiaomiFactory.generateCar(); Log.d("test", "Xiaomi phone name--->" + xiaomi11.phoneName()); Log.d("test", "xiaomiCar name--->" + xiaomiCar.carName()); } }
抽象工厂模式应用:Retrofit的CallAdapter
public interface CallAdapter<T> { Type responseType(); <R> T adapt(Call<R> call); abstract class Factory { public abstract CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit); protected static Type getParameterUpperBound(int index, ParameterizedType type) { return Utils.getParameterUpperBound(index, type); } protected static Class<?> getRawType(Type type) { return Utils.getRawType(type); } } }
工厂方法模式和抽象工厂模式都是创建型模式,区别如下:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
工厂方法模式的使用很简单,只要继承成子类,并实现工厂方法的工厂就可以了,而抽象工厂模式需要先实例化它,然后将它传入一些针对抽象类型所写的代码中。
工厂方法模式的优点是可以把一群相关的产品集合起来,而抽象工厂模式的优点是可以把一群相关的产品集合起来,并且创建整个产品家族的模式。
如果产品单一,只有一个产品等级结构适合使用工厂方法模式。如果存在多个产品等级,产品分类多个可以形成产品族合适使用抽象工厂模式。
工厂方法模式已经实现了开闭原则,但是有一个缺点,就是每增加一个产品,就得创建一个工厂类,而抽象工厂把这些工厂进行归类,
比如小米和华为,两个分组就好了。如果新增的产品属于小米的,就在小米工厂里面增加产品。如果新增的产品既不属于小米,
也不属于华为,就加一个工厂。
参考: