Java设计模式之工厂模式分析【简单工厂、工厂方法、抽象工厂】
作者:aronykl 发布时间:2021-07-07 21:11:57
本文实例讲述了Java设计模式之工厂模式。分享给大家供大家参考,具体如下:
一、 简单工厂
先来思考一个问题。我们平时写程序时,会有这种情况,A对象里面需要调用B对象的方法,这时我们使用的一般是new关键字来创建一个B实例,然后调用B实例的方法。这种做法的坏处在于:A类的方法实现直接调用了B类的类名(这种方式也被称为硬编码耦合),一旦系统需要重构:需要使用C类来代替B类时,程序就不得不修改A类代码,如果应用中有100个或者10000个类以硬编码方式耦合了B类,则需要修改100个、10000个地方,这显然是一种非常可怕的事情。
换一个角度来看这个问题:对已A对象而言,它只需要调用B对象的方法,并不关心B对象的实现、创建过程,考虑让B类实现一个IB接口,而A类只需要与IB接口耦合——A类并不直接使用new关键字来创建B实例,而是重新定义一个工厂类:IBFactory,由该工厂类负责创建IB实例,而A类用过调用IBFactory工厂的方法来得到IB的实例。通过以上设计:需要使用C类代替B类,则只需要让C类也实现IB接口,并改写IBFactory工厂中创建IB实例的实现代码,让该工厂产生C实例即可。这种将多个类对象交给工厂类来生成的设计方式叫做简单工厂模式。
以下是简单工厂模式的代码:
/**
* 简单工厂模式
*
* 需要工厂生产的对象实例所实现的共同的接口
* 发型接口
* @author Administrator
*
*/
public interface Hair {
/**
* 画发型
*/
public void draw();
}
/**
* 左偏分发型
* @author Administrator
*
*/
public class LeftHair implements Hair {
@Override
public void draw() {
System.out.println("----------------画左偏分发型-----------------");
}
}
/**
* 右偏分发型
* @author Administrator
*
*/
public class RightHair implements Hair {
@Override
public void draw() {
System.out.println("-----------------画右偏分发型------------------");
}
}
/**
* 生产发型的工厂
* 要生产什么发型 只需在这里改就行了
* @author Administrator
*
*/
public class HairFactory {
public Hair getHair() {
return new LeftHair();
//return new RightHair();
}
}
/**
* 客户端测试类
* @author Administrator
*
*/
public class HairTest {
public static void main(String[] args) {
HairFactory factory = new HairFactory();
Hair hair = factory.getHair();
hair.draw();
}
}
可以看到,如果想把HairTest里面生成的LeftHair改成RightHair,只需修改HairFactory里面getHair方法的实现即可。
使用简单工厂模式的优势在于:让对象的调用者和对象的创建过程分离,当对象调用者需要对象时,直接向工厂请求即可,从而避免了对象的调用者与对象实现类以硬编码方式耦合,以提高系统的可维护性、可扩展性。当然,工厂模式也有一个小小的缺陷,当产品修改时,工厂类也要做相应的修改,此处可使用策略模式进行解决,下面是代码。
public interface HairBuilder {
/**
* 制造发型
* @return
*/
public Hair getHair();
}
public class LeftHairBuilder implements HairBuilder {
@Override
public Hair getHair() {
return new LeftHair();
}
}
public class RightHairBuilder implements HairBuilder {
@Override
public Hair getHair() {
return new RightHair();
}
}
public class HairFactory {
private HairBuilder hairBuilder;
public HairFactory(HairBuilder hairBuilder) {
this.hairBuilder = hairBuilder;
}
public void setHairBuilder(HairBuilder hairBuilder) {
this.hairBuilder = hairBuilder;
}
public Hair getHair() {
return hairBuilder.getHair();
}
}
public class HairTest {
public static void main(String[] args) {
// HairBuilder builder = new LeftHairBuilder();
HairBuilder builder = new RightHairBuilder();
HairFactory factory = new HairFactory(builder);
Hair hair = factory.getHair();
hair.draw();
}
}
这种做法的好处是无需再去修改工厂类,将工厂里面的创建对量逻辑根据不同的策略抽象出来,程序需要创建什么对象,只需网工厂中传入相应的builder即可。
二、工厂方法
在简单工厂模式中,系统使用工厂类生产所有产品实例,且该工厂类决定生产哪个类的实例,即工厂类负责所有的逻辑判断、实例创建等工作。
如果不想再工厂类中进行逻辑判断,程序可以为不同的产品类提供不同的工厂,不同的工厂类生产不同的产品,无需再工厂类中进行复杂的逻辑判断。这就有点类似于上面的简单工厂模式结合策略模式,不同的是前者只有一个工厂,后者需要有多个工厂。下面是工厂方法模式的代码。
/**
* 工厂方法模式
* 需要工厂生产的对象实例所实现的共同的接口
* @author Administrator
*
*/
public interface Person {
public void drawPerson();
}
public class Man implements Person {
@Override
public void drawPerson() {
System.out.println("---------------------draw a man--------------------");
}
}
public class Women implements Person {
@Override
public void drawPerson() {
System.out.println("--------------------draw a women---------------------");
}
}
/**
* 生产人的工厂
* @author Administrator
*
*/
public interface PersonFactory {
//生产人
public Person getPerson();
}
/**
* 生产man的工厂
* @author Administrator
*
*/
public class ManFactory implements PersonFactory {
@Override
public Person getPerson() {
return new Man();
}
}
/**
* 声场women的工厂
* @author Administrator
*
*/
public class WomenFactory implements PersonFactory {
@Override
public Person getPerson() {
return new Women();
}
}
/**
* 客户端测试类
* @author Administrator
*
*/
public class PersonTest {
public static void main(String[] args) {
// PersonFactory factory = new ManFactory();
PersonFactory factory = new WomenFactory();
Person person = factory.getPerson();
person.drawPerson();
}
}
这种的典型的特点就是在客户端代码中根据不同的工厂生产其对应的产品,不必把复杂的逻辑都放在工厂类里面判断。这种实现有一个很明显的缺陷,就是客户端与工厂类进行了耦合。
三、抽象工厂
采用上面的工厂方法的设计架构,客户端代码成功与被调用对象的实现类分离,但带来了另一种耦合:客户端代码与不同的工厂类耦合。为了解决这种耦合的问题,考虑在增加一个工厂类,用来生成工厂实例,实现生产产品的工厂与客户端分离,这种设计方式被称为抽象工厂模式。下面是抽象工厂模式的代码
/**
* 抽象工厂模式
* 生产PersonFactory的工厂
* @author Administrator
*
*/
public class PersonFactoryFactory {
public static PersonFactory getPersonFactory(String type) {
if(type.equalsIgnoreCase("man")) {
return new ManFactory();
} else {
return new WomenFactory();
}
}
}
/**
* 客户端测试类
* @author Administrator
*
*/
public class PersonTest {
public static void main(String[] args) {
PersonFactory factory = PersonFactoryFactory.getPersonFactory("man");
Person person = factory.getPerson();
person.drawPerson();
}
}
更多java相关内容感兴趣的读者可查看本站专题:《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》
希望本文所述对大家java程序设计有所帮助。
来源:https://blog.csdn.net/zw19910924/article/details/52373892


猜你喜欢
- @RequestBody搭配@Data的坑如果用@Data修饰实体类,里面的属性最好不要用连续几个相同字母,如果用千万别用大写。比如下面这个
- 本文实例为大家分享了java实现二叉树遍历的具体代码,供大家参考,具体内容如下二叉树如下:遍历结果如下:以下是实现代码:package bi
- 1 环境部署1.1 jdk-8u111-windows-x64环境变量 JAVA_HOME:C:\Program Files\Java\jd
- 方法如下:在窗体的Load事件注册滚动事件,并增加对应的方法private void FormSample_Load(object send
- 本文实例讲述了C# winform实现右下角弹出窗口结果的方法。分享给大家供大家参考,具体如下:using System.Runtime.I
- 本文将带领大家使用基于JAX-RS REST风格的实现Jersey来上传文件到服务器制定的文件夹,如果是图片并读取显示出该图片。准备工作:准
- JDK8已发布,写了一个datetime时间函数使用方法的小示例package datetime;import static java.ti
- 1、效果展示2、布局文件<?xml version="1.0" encoding="utf-8"
- OkHttp 提供了对用户认证的支持。当 HTTP 响应的状态代码是 401 时,OkHttp 会从设置的 Authenticator 对象
- 在SpringBoot中,当需要获取到配置文件数据时,除了可以用Spring自带的@Value注解外,SpringBoot提供了一种更加方便
- 近日有朋友问我有没有如下图效果的开源控件相信大家无论是用IOS还是Android,都对这种效果不陌生,很多主流APP都会有这样或类似的效果,
- 配置文件m103替换为hdfs服务地址。要利用Java客户端来存取HDFS上的文件,不得不说的是配置文件hadoop-0.20.2/conf
- 为开发团队选择一款优秀的MVC框架是件难事儿,在众多可行的方案中决择需要很高的经验和水平。你的一个决定会影响团队未来的几年。要考虑方面太多:
- 对大部分系统来说都需要权限管理来决定不同用户可以看到哪些内容,那么如何在Spring MVC中实现权限验证呢?当然我们可以继续使用servl
- 一、什么是重量级锁当有大量的线程都在竞争同一把锁的时候,这个时候加的锁,就是重量级锁。这个重量级锁其实指的就是JVM内部的ObjectMon
- 本文实例为大家分享了android实现点击按钮控制图片切换的具体代码,供大家参考,具体内容如下代码:class MainActivity :
- 一、简介在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件。在Spring Cloud中,
- 一. 接口文档概述swagger是当下比较流行的实时接口文文档生成工具。接口文档是当前前后端分离项目中必不可少的工具,在前后端开发之前,后端
- Java类库及其组织结构(Java API)Java 官方为开发者提供了很多功能强大的类,这些类被分别放在各个包中,随JDK一起发布,称为J
- Spring容器可以在不使用<constructor-arg>和<property>元素的情况下自动装配相互协作的b