简单工厂模式的改进

本文探讨了如何通过反射优化简单工厂模式,以解决添加新咖啡类型时需要修改代码的问题。作者介绍了创建配置文件存储咖啡类路径,然后利用反射根据咖啡名称动态实例化对象的方法,实现了代码的开闭原则。在实践中,作者还注意到了中文编码问题,并分享了解决此问题的经验。
摘要由CSDN通过智能技术生成

之前对简单工厂模式一笔带过。今天我们来探究,如何优化简单工厂模式。
先来回顾一下代码

public abstract class Caffee {
    public abstract void GetCoffeMsg();//获取咖啡信息
}

public class CafeeLatte extends Caffee{
    @Override
    public void GetCoffeMsg() {
        System.out.println("这是拿铁咖啡");
    }
}


public class CaffeeAmeric extends Caffee {
    @Override
    public void GetCoffeMsg() {
        System.out.println("这是美式咖啡");
    }
}
public class CaffeFactory {
    public static Caffee getCaffee(String name){
        Caffee caffee=null;
        if("美式".equals(name)){
            caffee=new CaffeeAmeric();
        }else if("拿铁".equals(name)){
            caffee=new CafeeLatte();
        }else{
            System.out.println("抱歉,没有这种咖啡 Exception");
            return null;
        }
        return  caffee;
    }
}
public class CaffeeStore {
    /**
     * 模拟咖啡店对咖啡的包装
     * @param caffee
     */
    public void addSugar(Caffee caffee){
        System.out.println("咖啡店正在给咖啡加糖");
    }
    /**
     * 点咖啡
     * @param name 咖啡种类,这里用字符串代替
     */
    public void OrderCaffee(String name){
        Caffee caffee=CaffeFactory.getCaffee(name);
        this.addSugar(caffee);
        caffee.GetCoffeMsg();
    }

    //测试代码
    public static void main(String[] args) {
        CaffeeStore caffeeStore=new CaffeeStore();
        caffeeStore.OrderCaffee("美式");
        caffeeStore.OrderCaffee("拿铁");
    }
}

如果我们要加入一种咖啡:卡布奇诺,那么就需要修改工厂类的if分支,很明显不符合开闭原则,所以我们要想办法解决这个问题。其实可以利用反射,我们把需要加的类写在配置文件里,比如美式咖啡我们可以配置成:美式=com.CaffeeAmeric,然后通过反射进行实例化,添加新品种,只需要修改配置文件,不需要动代码,话不多说,直接上代码来解释说明
首先我创建了一个配置文件NeedCaffee,对应咖啡名和加载类名,各位要注意中文编码哦

美式=com.CaffeeAmeric
拿铁=com.CafeeLatte

配置文件一般由静态代码块加载,我们需要一张表来映射关系,以下代码概况起来就一句话,读取配置文件,映射到hashMap

   static {
        Properties propertiesIni=new Properties();
        InputStream ini=CaffeFactory.class.getClassLoader().getResourceAsStream("NeedCaffee");
        BufferedReader bf=null;
        try {
            bf = new BufferedReader(new InputStreamReader(ini, "UTF-8"));
            propertiesIni.load(bf);
            Set keySet=propertiesIni.keySet();
            Iterator iterator=keySet.iterator();
            while(iterator.hasNext()){
                String key=(String)iterator.next();
                CaffeeMap.put(key,propertiesIni.getProperty(key));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                bf.close();
                ini.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

映射完毕后,我们就能通过咖啡名获取到类路径,进而反射,创建对象

    public static Caffee getCaffee(String name){
        Caffee caffee=null;
        try {
            Class caffeeClass=Class.forName(CaffeeMap.get(name));
            caffee=(Caffee)caffeeClass.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  caffee;
    }

成功解决,学到了很多,不亲自动手试试,还没发现中文编码这个bug,果然,一些小细节不能丢,还有反射,语法忘了好多

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值