工厂模式

工厂模式实现

工厂模式的最终用途就是用来解耦,隔离用户和产品的关系。工厂只负责生产出标准,合格的产品,而用户不需要关心产品是如何被创建的,只需要按照自己的意愿选择一款自己喜好的产品即可。

1. 简单工厂

我们以国产牛奶举个例子,先定义一个牛奶生产的规范接口。

/**
 * 牛奶接口
 */
public interface Milk {
    String getName();
}

接下来就是具体的牛奶品牌商的实现了。

/**
 * 伊利牛奶
 */
public class Yili implements Milk {
    @Override
    public String getName() {
        return "伊利";
    }
}
/**
 * 蒙牛牛奶
 */
public class Mengniu implements Milk {
    @Override
    public String getName() {
        return "蒙牛";
    }
}
/**
 * 安慕希牛奶
 */
public class Anmuxi implements Milk{
    @Override
    public String getName() {
        return "安慕希";
    }
}
/**
 * 简单工厂实现
 */
public class SimpleFactory {
    public Milk getMilk(String type){
        if ("伊利".equals(type)){
            return new Yili();
        } else if ("蒙牛".equals(type)) {
            return new Mengniu();
        } else if ("安慕希".equals(type)) {
            return new Anmuxi();
        } else {
            System.out.println("没有发现对应类型的牛奶"+type);
        }
        return null;
    }
}
/**
 * 简单工厂测试类
 */
public class SimpleFactoryTest {
    public static void main(String[] args) {
        SimpleFactory factory = new SimpleFactory();
        System.out.println(factory.getMilk("蒙牛"));
        System.out.println(factory.getMilk("伊利"));
        System.out.println(factory.getMilk("安慕希"));
    }
}

简单工厂的缺点:
实现逻辑比较简单,但是它违背了设计模式的开闭原则,一旦我们需要添加其他的牛奶品牌,比如特仑苏,那么就需要在工厂类里面再加一个判断分支,这就代表对原有的代码逻辑进行了修改,而开闭原则的意思是尽量保证代码逻辑不要被多次修改(bug除外),也就是说面对新的需求时,我们只需要增加新代码(API),而不需要修改已经存在的代码。

2. 工厂方法

先定义一个标准的牛奶生产工厂协议,每个工厂都必须按照此标准进行产品生产。

/**
 * 标准的牛奶工厂协议
 */
public interface Factory {
    /**
     * 生产牛奶
     * @return
     */
    Milk getMilk();
}

伊利工厂遵照协议生产自己的牛奶,可能有不同的成分,配料,以及味道也会有所不同。

/**
 * 生产伊利的牛奶工厂
 */
public class YiliFactory implements Factory {
    /**
     * 生产伊利牛奶
     * @return
     */
    @Override
    public Milk getMilk() {
        return new Yili();
    }
}

同样,蒙牛工厂也遵照此协议并且按照自己特定的配方,配料生产牛奶。

/**
 * 生产蒙牛的牛奶工厂
 */
public class MengniuFactory implements Factory {
    /**
     * '生产蒙牛牛奶
     * @return
     */
    @Override
    public Milk getMilk() {
        return new Mengniu();
    }
}

同样,安慕希工厂也遵照此协议并且按照自己特定的配方,配料生产牛奶。

/**
 * 生产安慕希的牛奶工厂
 */
public class AnmuxiFactory implements Factory {
    /**
     * 生产安慕希牛奶
     * @return
     */
    @Override
    public Milk getMilk() {
        return new Anmuxi();
    }
}
/**
 * 工厂方法的测试类
 */
public class FactoryMethodTest {
    public static void main(String[] args) {
        //此时用户需要配置牛奶工厂
        //这对用户而言 还是不够直接 用户一般只对喜欢的牛奶产品感兴趣
        Factory factory = new AnmuxiFactory();
//        Factory factory = new YiliFactory();
//        Factory factory = new MengniuFactory();
        System.out.println(factory.getMilk());
    }
}

工厂方法相比较简单工厂而言,前者更加标准,专业。而且如果再来一个特仑苏牛奶,只需要再扩展一个工厂实现类就可以了,对用户而言他也只需要加以配置即可使用。

3. 抽象工厂

/**
 * 抽象工厂是以后用户面对的主入口
 */
public abstract class AbstractFactory {
    /**
     * 获得蒙牛品牌的牛奶
     * @return
     */
    public abstract Milk getMengniu();

    /**
     * 获得伊利平拍的牛奶
     * @return
     */
    public abstract Milk  getYili();

    /**
     * 获得安慕希品牌的牛奶
     * @return
     */
    public abstract Milk  getAnmuxi();
}

/**
 *具体的牛奶工厂
 */
public class MilkFactory extends AbstractFactory {
    @Override
    public Milk getMengniu() {
        return new MilkFactory().getMengniu();
    }

    @Override
    public Milk getYili() {
        return new YiliFactory().getMilk();
    }

    @Override
    public Milk getAnmuxi() {
        return new AnmuxiFactory().getMilk();
    }
}

/**
 * 抽象工厂测试类
 */
public class AbstractFactoryTest {
    public static void main(String[] args) {
        AbstractFactory factory = new MilkFactory();
        /**
         * 用户只需要选择相应的API就可以获得想要的产品
         * 比工厂方法模式更加简单直接了,不需要配置就可以使用
         */
        System.out.println(factory.getAnmuxi());
        System.out.println(factory.getMengniu());
        System.out.println(factory.getYili());
    }
}

抽象工厂模式在程序应用层面是使用的最广泛的,对用户而言,使用它能更简单直接的获取到自己想要的产品。
更少的配置,扩展也比较容易。如果再来一个特仑苏牛奶,我们只需要升级添加一个API,加入一个一个抽象方法即可,客户端(用户)无感知。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值