工厂模式

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);
    }
  }
}

 

工厂方法模式和抽象工厂模式都是创建型模式,区别如下:

    工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
    工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
    工厂方法模式的使用很简单,只要继承成子类,并实现工厂方法的工厂就可以了,而抽象工厂模式需要先实例化它,然后将它传入一些针对抽象类型所写的代码中。
    工厂方法模式的优点是可以把一群相关的产品集合起来,而抽象工厂模式的优点是可以把一群相关的产品集合起来,并且创建整个产品家族的模式。

如果产品单一,只有一个产品等级结构适合使用工厂方法模式。如果存在多个产品等级,产品分类多个可以形成产品族合适使用抽象工厂模式。

 

工厂方法模式已经实现了开闭原则,但是有一个缺点,就是每增加一个产品,就得创建一个工厂类,而抽象工厂把这些工厂进行归类,
比如小米和华为,两个分组就好了。如果新增的产品属于小米的,就在小米工厂里面增加产品。如果新增的产品既不属于小米,
也不属于华为,就加一个工厂。

 

参考:

https://zhuanlan.zhihu.com/p/610551658

posted @ 2023-09-21 11:03  蜗牛攀爬  阅读(31)  评论(0编辑  收藏  举报