show me the code and take to me,做的出来更要说的明白

GitHub项目JavaHouse同步收录

喜欢就点个赞呗! 你的支持是我分享的动力!

引入

我们经常听到工厂模式,比如说 Spring 用了工厂模式啦,面试也会被问到工厂模式等等,这见工厂模式是日常开发中比较重要的一种设计模式。其实工厂模式也是比较简单的一种设计模式,这年头似乎不了解工厂模式,你都不好意思说你学过 编程一样(手动狗头)。那么,允许我灵魂拷问一下,你真的了解工厂模式吗。

UML类图

不急,我们先看看 UML 类图。学习一下怎么用 UML 类图 表示代码。先看如何表示一个实体类。代码如下:

public class B {

    private String name;
private String password; public void test(){ }
}

这是一个简单的实体类。他的 看 UML 类图如下:

看完实体类,我们在来看看接口,代码如下:

public interface B {
void test();
}

这是一个简单的接类。一般接口就放几个方法,不放属性。他的 看 UML 类图如下:

看完实体类和接口,我们来看看他们有什么关系吧。先看看继承关系如何表示:

可以一眼看到他的箭头特点---空心的。箭头指向父类。这就是继承关系表示。

看完继承关系,我们在看看实现接口如何表示。

这里我们可以看到与继承关系类似,不过实现变成虚线,箭头指向接口类。

完了没有,没有,我们在看看依赖关系,这种关系比较弱,一般是一个类作为另一个类的参数表示, uml 图如下:

依赖关系是虚线,半个箭头

到这里,以上就是常见的 uml 类图表示。

简单工厂

进入正题,什么是工厂模式,我们先看看简单工厂模式,其实简单工厂模式并不是工厂模式,但是他可以帮助我们去了解工厂模式,所以我们先看看简单工厂模式。

需求:我们需要做一个可以加减乘除的计算机,运用到简单工厂模式。

UML 类图:

运算类:

import lombok.Data;

@Data
public abstract class Operation {
private Double numA;
private Double numB;
/**
* 运算方法
*/
abstract Double getResult();
}

加法类:

public class OperationAdd extends Operation{

    @Override
Double getResult() {
return getNumA() + getNumB();
}
}

乘法类:

public class OperationMul extends Operation{
@Override
Double getResult() {
return getNumA() * getNumB();
}
}

除法类:

public class OperationDiv extends Operation{
@Override
Double getResult() {
if (getNumB() == 0){
throw new RuntimeException("除数不能为零!");
}
return getNumA() / getNumB();
}
}

简单工厂类:

public class CreateOperationFactory {
public static Operation createOperation(String operate){
Operation operation = null;
switch (operate){
case "+":
operation = new OperationAdd();
System.out.println("这是+法");
break;
case "/":
operation = new OperationDiv();
System.out.println("这是/法");
break;
case "*":
operation = new OperationMul();
System.out.println("这是*法");
break;
}
return operation;
}
}

测试类:

public class Test {
public static void main(String[] args) {
Operation operation = CreateOperationFactory.createOperation("+");
operation.setNumA(1D);
operation.setNumB(2D);
System.out.println(operation.getResult()); operation = CreateOperationFactory.createOperation("*");
operation.setNumA(1D);
operation.setNumB(2D);
System.out.println(operation.getResult()); operation = CreateOperationFactory.createOperation("/");
operation.setNumA(1D);
operation.setNumB(2D);
System.out.println(operation.getResult());
}
}

输出接口:

这是+法
3.0
这是*法
2.0
这是/法
0.5

工厂模式

需求:要再添加一个减法运算,嗯?上面没有减法运算吗?我猜你们肯定没有发现上面没有减法运算。看到的也会以为我在偷懒了,蒙混过关呢。事情并没有这么简单。

一般来说,加个减法嘛,简单,我直接就下 工厂类里面加一个分支不就完事了。哈哈,殊不知,这时候,我们已经违反一个重要的原则--开放关闭原则。所谓开放关闭原则,我们不应该修源码,祖传代码你敢动,试试看,而是通过继承父类或者实现接口去拓展代码,达到我们的目的。

uml 类图:

代码如下:

public interface IFactory {
Operation createOperation(String operate);
} public class OperationAddFactory implements IFactory{
@Override
public Operation createOperation(String operate) {
Operation operation = new OperationAdd();
System.out.println("这是+法");
return operation;
}
}

抬杠

没错,这里是自己杠自己的环节。

什么工厂模式啊!我自己 new 一个对应的对象不就解决问题了,为啥要写一个工厂类出来。(杠上杠啊,这是要搞事情)

嗯?好像我无法反驳·····是不存在的(用我第三根手指推一推我的眼镜)。试想一下,一个地方用到就去 new 一下。我们一下new了十几个地方,然后发现要来类名,这时候,怎么办。一处一处改咯,自己new的对象,哭着也要改完。但是如果用工厂类的话,我们只需要改一个地方就可以,就是这么简单。

就这一个优点吗?我还是喜欢一个一个new啊。

肯定不是(这是一个杠精啊),当然简单一个new对象,确实不需要写一个类出来。但是new一个对象并不是那么简单,我们需要对象进行一个操作呢。Spring IOC机制默认创建对象是单例的,那么我们现在也需要对象是唯一的怎么办。这时候,我们就是可以在工厂类里面写一个单例模式,达到我们的目的。

以上就是我的抬杠环节。

总结

不管什么设计模式,其实就是为了代码复用,少写代码,我们做明白什么模式是什么模式,更要理解这些的作用。正所谓,武术的目的是为了生发,战争的出发点是为了和平。总之,就是知其然知其所以然。

看到这里的都是人才。

参考

https://juejin.im/post/5d318b485188255957377ac3#heading-4

《大话设计模式》

https://www.zhihu.com/question/24843188 -- 工厂设计模式有什么用?

关注微信公众号,随时移动端阅读

工厂设计模式灵魂拷问-Java实现的更多相关文章

  1. 【51】java设计模式-工厂设计模式剖析

    工厂设计设计模式的分类: 工厂模式在<Java与模式>中分为三类: 1)简单工厂模式(Simple Factory):不利于产生系列产品: 2)工厂方法模式(Factory Method) ...

  2. 灵魂拷问:为什么 Java 字符串是不可变的?

    在逛 programcreek 的时候,发现了一些精妙绝伦的主题.比如说:为什么 Java 字符串是不可变的?像这类灵魂拷问的主题,非常值得深思. 对于绝大多数的初级程序员来说,往往停留在" ...

  3. 灵魂拷问:Java 的 substring() 是如何工作的?

    在逛 programcreek 的时候,我发现了一些小而精悍的主题.比如说:Java 的 substring() 方法是如何工作的?像这类灵魂拷问的主题,非常值得深入地研究一下. 另外,我想要告诉大家 ...

  4. 灵魂拷问:如何检查Java数组中是否包含某个值 ?

    在逛 programcreek 的时候,我发现了一些专注细节但价值连城的主题.比如说:如何检查Java数组中是否包含某个值 ?像这类灵魂拷问的主题,非常值得深入地研究一下. 另外,我想要告诉大家的是, ...

  5. 灵魂拷问:创建 Java 字符串,用&quot;&quot;还是构造函数

    在逛 programcreek 的时候,我发现了一些小而精悍的主题.比如说:创建 Java 字符串,用 "" 还是构造函数?像这类灵魂拷问的主题,非常值得深入地研究一下. 01.& ...

  6. 灵魂拷问:Java对象的内存分配过程是如何保证线程安全的?(阿里面试)

    JVM内存结构,是很重要的知识,相信每一个静心准备过面试的程序员都可以清楚的把堆.栈.方法区等介绍的比较清楚. 上图,是一张在作者根据<Java虚拟机规范(Java SE 8)>中描述的J ...

  7. 利用Java反射机制优化简单工厂设计模式

    之前项目有个需求,审批流程的时候要根据配置发送信息:发送短信.发送邮件.当时看到这个就想到要用工厂模式,为什么要用工厂模式呢?用工厂模式进行大型项目的开发,可以很好的进行项目并行开发.就是一个程序员和 ...

  8. Java工厂设计模式

    程序在接口和子类之间加入一个过渡类,通过此过渡类端取得接口的实例化对象,一般都会称这个过渡端为工厂类 //=============================================== ...

  9. java简单工厂设计模式

    一.基本定义 /* *简单工厂设计模式: *文字描述理解: * 简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式. * 通过专门定义一个类来负责创建其它类的实例,被创建的实例通常 * 都具有共同 ...

随机推荐

  1. js控制复选框checkbox 只能单选

    我们在页面经常会用到单选框,来提供单值选在字段,但是有一个问题就是:一旦选择了就不能去除(即--只要选择了就不能再以空值提交了). 所以为了解决这个问题,用复选框限制单选是一个不错的选择 <sc ...

  2. 用LinkedList模拟栈数据结构的集合

    用Eclipse软件进行操作    有2种方法,左边为第一种,右边为第二种 创建class为MyStack 代码实现: package cn_LinkedList;   import java.uti ...

  3. 树状数组求逆序对:POJ 2299、3067

    前几天开始看树状数组了,然后开始找题来刷. 首先是 POJ 2299 Ultra-QuickSort: http://poj.org/problem?id=2299 这题是指给你一个无序序列,只能交换 ...

  4. (spring-第2回【IoC基础篇】)Spring的Schema,基于XML的配置

    要深入了解Spring机制,首先需要知道Spring是怎样在IoC容器中装配Bean的.而了解这一点的前提是,要搞清楚Spring基于Schema的Xml配置方案. 在深入了解之前,必须要先明白几个标 ...

  5. 二叉树、栈、队列、链表的Java代码实现

    这是我的学习总结. 如有文章存在谬误,欢迎指出,有其他意见或者建议,也欢迎留言 二叉树链表 前序遍历:先访问根节点,然后访问左子树.右子树 中序遍历:先访问左子树,然后访问根节点.右子树 后序遍历:先 ...

  6. docker 安装 MySQL 8,并减少内存占用 记录

    目前vps 1cpu 512m内存 MySQL内存占用77% ,约350m ,经过修改配置文件优化后如下 $ ps aux 进入docker bash $ docker exec -it pwc-my ...

  7. Java SE之I/O流:知识框架

  8. 源码:Java集合源码之:哈希表(二)

    要想知道一个元素是否在数组或链表中,只能从前向后挨个对比,无论是数组还是链表,其对数据的查询表现都比较无力.在的二叉排序树中,还会将数据排序以进行二分查找,将时间复杂度从O(n)降低到O(lg n). ...

  9. JS的浅拷贝与深拷贝

    浅拷贝 //这样的拷贝有一个问题.那就是,如果父对象的属性等于数组或另一个对象,//那么实际上,子对象获得的只是一个内存地址,而不是真正拷贝,因此存在父对象被篡改的可能. function exten ...

  10. char *直接赋值和strcpy之间什么区别

    赋值是两个指针指向同一个位置. 而strcpy则是把内容拷贝了一份给另个一指针.