简单工厂模式~

我们以生产手机作为应用场景展开讲解!

手机是一个抽象的概念,它包含很多的品牌,例如华为,苹果,小米等等,因此我们可将其抽象为一个接口,如下所示:

java 复制代码
public interface tel {
    void produce();
}

苹果手机作为手机的实现类之一实现手机的接口:

java 复制代码
public class appleTel implements tel{
    @Override
    public void produce() {
        System.out.println("苹果手机");
    }
}

华为手机也是如此

java 复制代码
public class huaweiTel implements tel{
    @Override
    public void produce() {
        System.out.println("华为手机");
    }
}

客户端代码:

java 复制代码
public class test {
    public static void main(String[] args) {
    	//生产苹果手机---创建对应的实例对象
        tel tel=new appleTel();
        tel.produce();
        //生产华为手机---创建对应的实例对象
        tel tel1=new huaweiTel();
        tel1.produce();
    }
}

如上所示为客户端,每生产一个产品就要实现创建实现类的实例化对象,这种方式既包含对象的创建也包含对象的实现,其耦合度很高,为了将对象的创建与使用分离隐藏具体实现细节,提高代码的灵活性,我们引入了工厂模式

如下所示我们创建工厂类:

它的作用是将对象的创建逻辑封装起来,其中我们通过if-else语句对客户端传递的参数进行判断,创建对应的实现类的实例化对象,

java 复制代码
public class telfactory {
    public tel create(String name){
        if(name.equals("华为")){
            return new huaweiTel();
        } else if(name.equals("苹果")){
            return new appleTel();
        }else {
            return null;
        }
    }
}

客户端代码修改如下所示:

与上述相比,我们将具体对象的创建过程隐藏在工厂类中客户端只需关心所需对象的接口,而无需关心具体的实现细节。这样可以保护对象的具体实现细节提高代码的安全性

java 复制代码
public class test {
    public static void main(String[] args) {
        //工厂模式---只需要创建工程类的实例化对象,其实现类的对象创建过程在工厂类中完成
        telfactory telfactory=new telfactory();
        telfactory.create("苹果").produce();
        telfactory.create("华为").produce();
    }
}

上述我们是在工厂类中通过if-else语句进行判断后创建对应的实现类实例化对象,这种方式有很多缺点,它不符合开闭原则,假设未来我们有了更多的实现类,那么必须修改工厂类中的if-else,代码的灵活性并不高。

对此,我们可以再进行优化,在工厂类中我们的判断逻辑不在具体到每个实现类上,而是只需要判断客户端给定的类名通过反射创建的实例对象是否可以上转型成我们的接口类型。

java 复制代码
public class telfactory {
    public tel create(String classname) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
    //根据在客户端给定的类名,返回一个Class对象,该对象表示与客户端指定类名对应的类,再调用newInstance(),创建该类的一个实例对象。再将其通过上转型转化为tel接口类型
        if(!(null==classname||"".equals(classname))) {
            return (tel) Class.forName(classname).newInstance();
        }
        return null;
    }
}

客户端只需要指定类名,但是需要注意传入的必须是全类名

java 复制代码
public class test {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        telfactory telfactory=new telfactory();
        //传入全类名,以便通过反射创建对应的实现类的实例化对象
        telfactory.create("com.wjr.demo1.telFactory.appleTel").produce();
        telfactory.create("com.wjr.demo1.telFactory.huaweiTel").produce();
    }
}

上述对工厂类中的代码进行了优化,但客户端需要传入的是字符串的全类名,而且只有当运行之后我们才知道传入的类名是否有问题,这显然不利于我们测试,因此我们可以修改客户端传入的参数类型,通过泛型限定限定传入的类必须为实现当前接口,假设我们在客户端传入的类不符合,编译器也会及时的报错,以便我们修改和检查

java 复制代码
public class telfactory {
    public tel create(Class <? extends tel> clazz) throws ClassNotFoundException, InstantiationException, IllegalAccessException {//通过泛型限定传入的类型必须是tel的实现类
        if(!(null==clazz||"".equals(clazz))) {
            return clazz.newInstance();
        }
        return null;
    }
}
java 复制代码
public class test {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        telfactory telfactory=new telfactory();
        telfactory.create(com.wjr.demo1.telFactory.appleTel.class).produce();
        telfactory.create(com.wjr.demo1.telFactory.huaweiTel.class).produce();
    }
}
相关推荐
lang20150928几秒前
Spring Boot 入门:5分钟搭建Hello World
java·spring boot·后端
失散1310 分钟前
分布式专题——47 ElasticSearch搜索相关性详解
java·分布式·elasticsearch·架构
爱喝白开水a10 分钟前
LangChain 基础系列之 Prompt 工程详解:从设计原理到实战模板_langchain prompt
开发语言·数据库·人工智能·python·langchain·prompt·知识图谱
serve the people12 分钟前
LangChain 表达式语言核心组合:Prompt + LLM + OutputParser
java·langchain·prompt
想ai抽14 分钟前
深入starrocks-多列联合统计一致性探查与策略(YY一下)
java·数据库·数据仓库
Neverfadeaway22 分钟前
【C语言】深入理解函数指针数组应用(4)
c语言·开发语言·算法·回调函数·转移表·c语言实现计算器
武子康23 分钟前
Java-152 深入浅出 MongoDB 索引详解 从 MongoDB B-树 到 MySQL B+树 索引机制、数据结构与应用场景的全面对比分析
java·开发语言·数据库·sql·mongodb·性能优化·nosql
杰克尼27 分钟前
JavaWeb_p165部门管理
java·开发语言·前端
longgyy38 分钟前
5 分钟用火山引擎 DeepSeek 调用大模型生成小红书文案
java·数据库·火山引擎
一成码农1 小时前
JavaSE面向对象(下)
java·开发语言