1.简单工厂模式(Factory Method

常用的工厂模式是静态工厂模式,利用static修饰方法,作为一种类似于常见的工具类Utils等辅助效果,一般情况下工厂类不需要实例化。

//1.定义一个基类接口
public interface Video {
//定义一个生产视频的方法
public void produce();
}
//2.定义实现类
public class JavaVideo implements Video {
@Override
public void produce() {
System.out.println("生产java视频");
}
}
public class PythonVideo implements Video {
@Override
public void produce() {
System.out.println("生产python视频的方法");
}
}
//3.定义视频工厂
public class VideoFactory {
public static Video getVideo(String type) {
if("java".equalsIgnoreCase(type)) {
return new JavaVideo();
}else if("python".equalsIgnoreCase(type)) {
return new PythonVideo();
}else {
return null;
}
}
}
//4.测试类
public class Test {
public static void main(String[] args) {
Video video = VideoFactory.getVideo("java");
if(video==null) {
return;
}
video.produce();
}
}

工厂模式缺点:

工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,违反开闭原则。但上述工厂类模式随着生产课程种类原来越多,工厂里的方法要不断修改,不符合开闭原则。

改进:

1.1.  利用反射弥补扩展性,重新定义VideoFactory内的getVideo方法。

//修改工厂类
public class VideoFactory01 {
public static Video getVideo(Class<?> c) {
Video video=null;
try {
video=(Video) Class.forName(c.getName()).newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return video;
}
}
//测试类
public class Test1 {
public static void main(String[] args) {
Video video = VideoFactory01.getVideo(PythonVideo.class);
video.produce();
}

1.2.工厂类只定义规范(接口),创建不同的实例只需要不同的工厂类实现统一的工厂接口即可。这样可以放VideoFactory这个超类代码与子类创建对象的代码解耦。(工厂模式)

//视频工厂只提供规范,具体创建何种实例由具体的工厂实现类来决定
public interface VideoFactory02 {
public Video getVideo();
}
//具体的实现
public class JavaVideoFactory02 implements VideoFactory02 {
@Override
public Video getVideo() {
return new JavaVideo();
}
}
public class PythonVideoFactory02 implements VideoFactory02 {
@Override
public Video getVideo() {
// TODO Auto-generated method stub
return new PythonVideo();
}
}
//测试类
public class Test2 {
/**
* 现在创建什么类型的视频是由VideoFactory的子类决定的,VideoFactory只定义规范,契约
* @param args
*/
public static void main(String[] args) {
VideoFactory02 factory=new JavaVideoFactory02();
Video video= factory.getVideo();
video.produce();
}
}

从扩展性的角度来看,现在如果要添加一门前端课程,只需要创建FeVideoFactory实现VideoFactory接口就可以了,不需要修改VideoFactory的代码实现。符合开闭原则。且FeVideo,JavaVideo,PythonVideo处于同一产品等级,工厂模式就是方便解决同一产品等级创建实例的。

2.工厂模式深入——体现产品等级概念

      举个栗子:假设我们想要找电脑组装人员DIY组装一台电脑。我们希望自己选择CPU、主板、内存、电源、显卡、电源等。由于内容较多,我们就拿CPU和主板来说事。

在选择CPU的时候,主要的参数有CPU品牌,型号,针脚数量,主频等,只有这些都确定下来,我们才能确定具体的CPU;

主板也一样,主板的主要参数有品牌,芯片组,总线频率等,只有这些确定下来,我们才能确定具体主板;

且在选择的时候我们还需要考虑到CPU和主板的兼容性,比如说Intel的CPU与AMD的主板就不兼容,因为Intel的CPU的针脚数目与AMD主板的CPU插孔数量不一致,根本无法插入。所以装机方案需要整体考虑,里边的不同模块之间是有关联的。

对于装机工程师来说,他只知道组装一台电脑需要响应的配件,而具体的配件选择还是需要由客户决定。对于不同的客户做出的选择不同,他需要根据客户的选择去获取配件,然后为该客户完成组装。

  使用工厂模式的解决方案:

     对于装机工程师来说,他只知道组装电脑需要CPU和主板,而两者具体选择什么品牌,型号他确定不了,需要客户去选择,客户选择好后他负责去相应的工厂里边获取这两种配件,然后组装。

2.1.Cpu接口与具体实现

//Cpu接口
package com.itheima.pattern.entity;
public interface CPU {
//CPU具有计算功能
public void calculate();
}
//Cpu具体实现Intel,可供客户选择
package com.itheima.pattern.entity; public class IntelCpu implements CPU {
private int pins;
public IntelCpu(int pins) {
this.pins = pins;
} @Override
public void calculate() {
System.out.println("Intel Cpu的针脚数:"+pins);
}
}
//Cpu具体实现Amd,可供客户选择
package com.itheima.pattern.entity; public class AmdCpu implements CPU { private int pins;
public AmdCpu(int pins) {
this.pins = pins;
}
@Override
public void calculate() {
System.out.println("Amd Cpu针脚数:"+pins);
}
}

2.2.主板接口与具体实现

//主板接口
package com.itheima.pattern.entity; public interface Mainboard {
//主板上安装Cpu
public void installCpu();
} //主板具体实现Intel,可供客户选择
package com.itheima.pattern.entity; public class IntelMainboard implements Mainboard {
/**
* cpu插槽孔数
*/
private int cpuHolds;
public IntelMainboard(int cpuHolds) {
this.cpuHolds = cpuHolds;
} @Override
public void installCpu() {
System.out.println("Intel主板CPU插槽孔数是:"+cpuHolds);
}
} //主板具体实现Amd,可供客户选择
package com.itheima.pattern.entity; public class AmdMainboard implements Mainboard {
private int cpuHolds;
public AmdMainboard(int cpuHolds) {
this.cpuHolds = cpuHolds;
}
@Override
public void installCpu() {
System.out.println("Amd 主板Cpu插槽孔数:"+cpuHolds);
}
}

2.3.创建Cpu工厂

package com.itheima.pattern.factory;

import com.itheima.pattern.entity.AmdCpu;
import com.itheima.pattern.entity.CPU;
import com.itheima.pattern.entity.IntelCpu; public class CpuFactory { public static CPU createCpu(int type) {
CPU cpu=null;
if(type==1) {
cpu=new IntelCpu(755);
}else if(type==2) {
cpu=new AmdCpu(938);
}else {
return null;
}
return cpu;
}
}

2.4.创建主板工厂

package com.itheima.pattern.factory;

import com.itheima.pattern.entity.AmdMainboard;
import com.itheima.pattern.entity.IntelMainboard;
import com.itheima.pattern.entity.Mainboard; public class MainboardFactory {
public static Mainboard createMainboard(int type) {
if(type==1) {
return new IntelMainboard(755);
}else if(type==2) {
return new AmdMainboard(938);
}else {
return null;
}
}
}

2.5.电脑组装工程师(工厂调用者)

package com.itheima.pattern.computerEngineer;

import com.itheima.pattern.entity.CPU;
import com.itheima.pattern.entity.Mainboard;
import com.itheima.pattern.factory.CpuFactory;
import com.itheima.pattern.factory.MainboardFactory; public class ComputerEngineer {
//装机需要Cpu
private CPU cpu;
//装机需要主板
private Mainboard mainboard;
//组装电脑
public void makeComputer(int cpuType,int boardType) {
cpu=CpuFactory.createCpu(cpuType);
mainboard=MainboardFactory.createMainboard(boardType);
cpu.calculate();
mainboard.installCpu();
System.out.println("电脑组装完成,可以使用");
}
}

2.6.客户(使用者)

package com.itheima.pattern.client;

import com.itheima.pattern.computerEngineer.ComputerEngineer;

public class Client {
public static void main(String[] args) {
ComputerEngineer computerEngineer = new ComputerEngineer();
computerEngineer.makeComputer(1, 1);
}
}

2.7.程序运行结果

上边的实现是采用简单工厂模式实现的,但有个问题没有解决,就是Cpu与主板之间的兼容关系没有解决,实际上Cpu与主板之间时候有关系的,需要相互匹配。而上边的实现并没有维护这种关系。因此当客户选择makeComputer(1, 2)时,将出现无法组装的情况。该如何避免这种情况的发生?需要引入抽象工厂模式。见下一节。

1.Java设计模式-工厂模式的更多相关文章

  1. 【设计模式】Java设计模式 -工厂模式

    [设计模式]Java设计模式 -工厂模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! 目 ...

  2. 一张图搞定Java设计模式——工厂模式! 就问你要不要学!

    小编今天分享的内容是Java设计模式之工厂模式. 收藏之前,务必点个赞,这对小编能否在头条继续给大家分享Java的知识很重要,谢谢!文末有投票,你想了解Java的哪一部分内容,请反馈给我. 获取学习资 ...

  3. 10.Java设计模式 工厂模式,单例模式

    Java 之工厂方法和抽象工厂模式 1. 概念 工厂方法:一抽象产品类派生出多个具体产品类:一抽象工厂类派生出多个具体工厂类:每个具体工厂类只能创建一个具体产品类的实例. 即定义一个创建对象的接口(即 ...

  4. 学习:java设计模式—工厂模式

    一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类: 1)简单工厂模式(Simple Facto ...

  5. Java设计模式---工厂模式(简单工厂、工厂方法、抽象工厂)

    工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类.工厂模式的形态工厂模式主要用一下几种形态:1:简单工厂(Simple Factory).2:工厂方法(Factory M ...

  6. java设计模式-工厂模式(springweb为例子)

    一般而言,工厂模式分为3种,简单工厂模式,工厂方法模式,抽象工厂模式.这三种工厂模式逐层深入吧. 一,从springWeb.jar包使用抽象工厂模式的一个例子聊起 之前对spring各种痴迷,所以在需 ...

  7. java设计模式—工厂模式

    一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类:1)简单工厂模式(Simple Factor ...

  8. Java设计模式——工厂模式

    一.工厂模式分类 工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类: (1)简单工厂模式(Simp ...

  9. Java设计模式の工厂模式

    -------------------------------------------------------- 目录:  一.序言 二.简单工厂模式 三.工厂方法模式 四.简单工厂和工厂方法模式的比 ...

随机推荐

  1. java 获取一个整数的各个位数

    两种方法~  第一种是取模运算  第二种是使用char数组进行分割开依次存到数组[推荐第二种] 获取一个四位数的各个位数 int qian =input/1000; //千位除以1000       ...

  2. BZOJ 1091--切割多边形(几何&枚举)

    1091: [SCOI2003]切割多边形 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 356  Solved: 157[Submit][Status ...

  3. Oauth2.0 整合springCloud的Zuul 解决关键BUG 报错信息:Principal must not be null

    不清楚Oauth2.0 的 可以查看我前几篇博文 2018.4.8 补充 我出现这个原因:是我在资源服务器使用了 如下图所示 Principal Oauth2.0 提供的获取用户信息的方法 使其找到相 ...

  4. 深度解析CNN

    [1]Deep learning简介 [2]Deep Learning训练过程 [3]Deep Learning模型之:CNN卷积神经网络推导和实现 [4]Deep Learning模型之:CNN的反 ...

  5. java学习笔记_接口

    接口:interface(关键字) public interface USB {} 1. 接口中都是抽象方法,方法前面的可见度(public.private)和抽象关键字(abstract)可以不写. ...

  6. java 实现七大基本排序算法

    一. 选择排序 /** * 选择排序: int arr[] = { 5, 6, 2, 7, 8, 6, 4 }; * * 第0趟 5 2 6 7 6 4 8 第1趟 2 5 6 6 4 7 8 第2趟 ...

  7. 2016级算法第六次上机-C.AlvinZH的学霸养成记II

    1032 AlvinZH的学霸养成记II 思路 中等题,贪心. 所有课程按照DDL的大小来排序. 维护一个当前时间curTime,初始为0. 遍历课程,curTime加上此课程持续时间d,如果这时cu ...

  8. windows安装tesseract-OCR及使用

    tesseract是Python的一个OCR(光学字符识别)库 首先下载tesseract的exe安装文件   https://github.com/UB-Mannheim/tesseract/wik ...

  9. 问题 C: 调酒壶里的酸奶 广搜或深搜+记忆化搜索

    问题 C: 调酒壶里的酸奶 时间限制: 1 Sec  内存限制: 128 MB提交: 284  解决: 97[提交] [状态] [命题人:外部导入] 题目描述 最近小w学了一手调酒的技巧,这么帅的操作 ...

  10. [转] etcd 搭建与使用

    [From] https://blog.csdn.net/ShouTouDeXingFu/article/details/81167302 etcd 1.下载etcd二进制文件包         ht ...