精华内容
下载资源
问答
  • MagicEXIF 还允许用户使用动态时间,每完成处理一张的拍摄时间后系统会为这个时间自动加上一个指定范围的值作为下一张的拍摄时间,整个过程用户无需介入,省时省力 常见问题: 1、运行 MagicEXIF 元数据编辑器...
  • 项目中的if else太多了,该怎么重构? 原创Java识堂 发布于2019-11-09 16:23:09 阅读数 44440 收藏 展开 介绍 最近跟着公司的大佬开发了一款IM系统,类似QQ和微信哈,就是聊天软件。我们有一部分业务逻辑是这样的 ...

    项目中的if else太多了,该怎么重构?
    原创Java识堂 发布于2019-11-09 16:23:09 阅读数 44440  收藏
    展开

    介绍
    最近跟着公司的大佬开发了一款IM系统,类似QQ和微信哈,就是聊天软件。我们有一部分业务逻辑是这样的

    if (msgType = "文本") {
        // dosomething
    } else if(msgType = "图片") {
        // doshomething
    } else if(msgType = "视频") {
        // doshomething
    } else {
        // doshomething
    }

    就是根据消息的不同类型有不同的处理策略,每种消息的处理策略代码都很长,如果都放在这种if else代码快中,代码很难维护也很丑,所以我们一开始就用了策略模式来处理这种情况。

    策略模式还挺简单的,就是定义一个接口,然后有多个实现类,每种实现类封装了一种行为。然后根据条件的不同选择不同的实现类。

    实现过程
    消息对象,当然真实的对象没有这么简单,省略了很多属性

    @Data
    @AllArgsConstructor
    public class MessageInfo {

        // 消息类型
        private Integer type;
        // 消息内容
        private String content;

    }

    定义一个消息处理接口

    public interface MessageService {

        void handleMessage(MessageInfo messageInfo);
    }

    有2个消息处理接口,分别处理不同的消息

    处理文本消息

    @Service
    @MsgTypeHandler(value = MSG_TYPE.TEXT)
    public class TextMessageService implements MessageService {

        @Override
        public void handleMessage(MessageInfo messageInfo) {
            System.out.println("处理文本消息 " + messageInfo.getContent());
        }
    }

    处理图片消息

    @Service
    @MsgTypeHandler(value = MSG_TYPE.IMAGE)
    public class ImageMessageService implements MessageService {

        @Override
        public void handleMessage(MessageInfo messageInfo) {
            System.out.println("处理图片消息 " + messageInfo.getContent());
        }
    }

    文章写到这,可能大多数人可能会想到要需要如下一个Map, Map<消息类型,消息处理对象>,这样直接根据消息类型就能拿到消息处理对象,调用消息处理对象的方法即可。我们就是这样做的,但是我们不想手动维护这个Map对象,因为每次增加新的消息处理类,Map的初始化过程就得修改

    我们使用了注解+ApplicationListener来保存这种映射关系,来看看怎么做的把

    定义一个消息类型的枚举类

    public enum MSG_TYPE {

        TEXT(1, "文本"),
        IMAGE(2, "图片"),
        VIDEO(3, "视频");

        public final int code;
        public final String name;

        MSG_TYPE(int code, String name) {
            this.code = code;
            this.name = name;
        }
    }

    定义一个注解

    @Documented
    @Inherited
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MsgTypeHandler {

        MSG_TYPE value();
    }

    不知道你注意到了没,前面的代码中,每种消息处理类上面都有一个@MsgTypeHandler注解,表明了这个处理类
    处理哪种类型的消息

    @Service
    @MsgTypeHandler(value = MSG_TYPE.TEXT)
    public class TextMessageService implements MessageService {

        @Override
        public void handleMessage(MessageInfo messageInfo) {
            System.out.println("处理文本消息 " + messageInfo.getContent());
        }
    }

    用一个context对象保存了消息类型->消息处理对象的映射关系

    @Component
    public class MessageServiceContext {

        private final Map<Integer, MessageService> handlerMap = new HashMap<>();

        public MessageService getMessageService(Integer type) {
            return handlerMap.get(type);
        }

        public void putMessageService(Integer code, MessageService messageService) {
            handlerMap.put(code, messageService);
        }

    }

    最精彩的部分到了

    @Component
    public class MessageServiceListener implements ApplicationListener<ContextRefreshedEvent> {

        @Override
        public void onApplicationEvent(ContextRefreshedEvent event) {
            Map<String, Object> beans = event.getApplicationContext().getBeansWithAnnotation(MsgTypeHandler.class);
            MessageServiceContext messageServiceContext = event.getApplicationContext().getBean(MessageServiceContext.class);
            beans.forEach((name, bean) -> {
                MsgTypeHandler typeHandler = bean.getClass().getAnnotation(MsgTypeHandler.class);
                messageServiceContext.putMessageService(typeHandler.value().code, (MessageService) bean);
            });
        }
    }

    在spring的启动过程中,通过解析注解,将消息类型->消息处理对象的映射关系保存到MessageServiceContext对象中

    @Autowired
    MessageServiceContext messageServiceContext;

    @Test
    public void contextLoads() {
        // 构建一个文本消息
        MessageInfo messageInfo = new MessageInfo(MSG_TYPE.TEXT.code, "消息内容");
        MessageService messageService = messageServiceContext.getMessageService(messageInfo.getType());
        // 处理文本消息 消息内容
        // 可以看到文本消息被文本处理类所处理
        messageService.handleMessage(messageInfo);
    }

    测试类正常工作,通过策略模式避免了写大量的if else代码,也更容易维护
    ————————————————
    版权声明:本文为CSDN博主「Java识堂」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/zzti_erlie/article/details/102988486

    展开全文
  • 图软件软件简介 美图网旗下产品——美图看看是目前最小最快的万能看图软件,完美兼容所有主流图片格式,用户好评度极高。美图看看采用自主研发的图像引擎,专门针对数码照片优化,使大图片的浏览性能全面提升!...
  • 近日,公司需要重构一款引用google地图的app,本想用uni-app下手,发现web-view的坑真的爬不出来,挣扎一番后,弃之投vue。 google账号 想要制作google地图,账号是必须的,还有翻墙软件,参考谷歌官网 或者网上搜下...

    近日,公司需要重构一款引用google地图的app,本想用uni-app下手,发现web-view的坑真的爬不出来,挣扎一番后,弃之投vue。

    google账号

    想要制作google地图,账号是必须的,还有翻墙软件,参考谷歌官网 或者网上搜下很多,这里就不多说。
    而且需要开通结算账号,否则地图就会有一层水印遮罩层。

    项目中引入地图

    首先引入谷歌地图 详细可看npm官网

    npm install vue2-google-maps
    

    在main.js中引入

    // main.js
    import Vue from 'vue'
    import * as VueGoogleMaps from 'vue2-google-maps'
     
    Vue.use(VueGoogleMaps, {
      load: {
        key: 'YOUR_API_TOKEN',
        libraries: 'places', // This is required if you use the Autocomplete plugin
        // OR: libraries: 'places,drawing'
        // OR: libraries: 'places,drawing,visualization'
        // (as you require)
     
         If you want to set the version, you can do so:
        // v: '3.26',
      },
     
       If you intend to programmatically custom event listener code
       (e.g. `this.$refs.gmap.$on('zoom_changed', someFunc)`)
       instead of going through Vue templates (e.g. `<GmapMap @zoom_changed="someFunc">`)
       you might need to turn this on.
      // autobindAllEvents: false,
     
       If you want to manually install components, e.g.
       import {GmapMarker} from 'vue2-google-maps/src/components/marker'
       Vue.component('GmapMarker', GmapMarker)
       then disable the following:
      // installComponents: true,
    })
    

    在需要引入的页面中

    <GmapMap
      :center="{lat:10, lng:10}"
      :zoom="7"
      map-type-id="terrain"
      style="width: 500px; height: 300px"
    >
      <GmapMarker
      @dragend="updateMaker"
        :key="index"
        v-for="(m, index) in markers"
        :position="m.position"
        :clickable="true"
        :draggable="true"
        @click="center=m.position"
      />
    </GmapMap>
    <script>
        export default {
            data() {
                return {
                    centers: {lat: 39.90419989999999,lng: 116.4073963},
                    markers: [{
                        position: {lat: 39.90419989999999,lng: 116.4073963}
                    }]
                }
            },
            methods:{
            	updateMaker: function(event) {
                    console.log('updateMaker, ', event.latLng.lat());
                    this.markers[0].position = {
                        lat: event.latLng.lat(),
                        lng: event.latLng.lng(),
                    }
                },
            }
     }
    

    以上便完成基本的地图引入过程,这样就结束了吗?真正的坑现在才来,重点来了~~

    深入了解谷歌api

    如果你只是调用谷歌地图看下,那你已经可以点赞退出了,但是大部分人需要使用谷歌地图进行一系列定位,定图标,调用后台数据渲染地图之类的,显然这才是重点。
    谷歌地图同百度地图一样,有两种调用方式,我在上一篇中有讲解 vue引入百度地图 ,首先引入

    <gmap-map
          id="map"
          :center="centers"
          style="width: 100%; height: calc(100vh - 2rem);margin-top:1rem;"
        >
    </gmap-map>
    

    然后发现无法引用方法,没错了,这是我选择了谷歌官网api,发现了一个好东西
    大事件
    通过一系列的判断、测试、实验。。。
    皮卡丘,决定就是你了,不对不对,是idle(通过判断事件的发生以及先后的顺序决定),于是乎在这个方法中你就可以打印出google 这个对象;

     <gmap-map
          id="map"
          :center="centers"
          style="width: 100%; height: 100vh;"
          @idle="handler"
        >
        </gmap-map>
        
    <script>
    export default {
      data: () => ({
        centers: { lat: 22.6502, lng: 113.2402 }
      }),
      methods: {
      	handler(){
      		console.log(google);
      		// 实例化地图
      		let map = new google.maps.Map(document.getElementById("map"), {
            zoom: 8,
            center: this.centers,
            // 地图类型 默认
            mapTypeId: "roadmap"
            // 禁用默认控件 便于修改控件样式 自定义控件 自定义位置
            // disableDefaultUI: true
          });
      	}
      }
    }
    </script>
    

    打印出这对象那就可以肆意地使用google的api进行添加方法了,首先,来尝试添加图标(或自定义图标)
    注:引用本地图片使用require
    官方自定义图标

    handler(){
    	
    	...
    	
    	 const marker = new google.maps.Marker({
                position: pos,
                // 不写icon默认为旗标图标
                // 引用本地图片使用require
                icon: require("../assets/caron.png"),
                map: map
              });
         // 点击定标
        marker.addListener("click", function(){
        	console.log(1)
        });     
     }
    

    也可以给每个图标添加信息窗口,点击打开或关闭 官方方法---- 信息窗口
    在这里插入图片描述
    可以根据自己需要的api自行添加方法,这就不一一说明,看官方示例都有。

    希望以上对你有帮助,不要忘记点赞哦
    有什么错误的,望不吝赐教,谢谢~~

    展开全文
  • 开始机房收费系统重构也半个月过去了。但看自己的系统连一个简略的登录还没有实现。自己不免有些羞愧了。近来自己的习学态状总的说来还是不错的。但是由于自己对来的识知把握的欠好所以致导了自己不知如何手下。...

    这段间时一直在查找程序集系统之类的问题,在现正好有机会和大家同享一下.

            开始机房收费系统重构也半个月过去了。但看自己的系统连一个简略的登录还没有实现。自己不免有些羞愧了。近来自己的习学态状总的说来还是不错的。但是由于自己对来原的识知把握的欠好所以致导了自己不知如何手下。老是觉感有很多多少的问题要决解:

        

    1. 写软件发开档文。
      1. 画数据流程图
      2. E-R
    2. uml
      1. 习学应用EA
    3. 建立数据库
      1. 习学触发器的应用
      2. 习学存储过程的建了与应用
      3. 习学数据库的范规化
      4. 习学ADO.net
      5. 习学应用SqlHelper对数据库拜访类的封装。
    4. 应用设计模式
      1. 尽可能多的应用设计模式。
    5. 应用三层构架
    6. 习学应用定名范规

            把这些问题都列出来,现发都是前以学过的内容。但是由于自己时当学的不踏实在现只能回过头来都看一遍了。返回去看了很多多少同窗的博客,觉感获收挺大的。

        

            通过半个多月的的大习复。天几前终究开始我的机房收费系统个人版了。先从写档文开始,但是我现发写到概要设计的时候我实在是写不下去了。原因是要写数据字典和接口实现。记得自己版一第的机房收费系统是在系统经已实现的前提下写的。写档文的时候可以看着系统一点一点的写。自己用了那几个法方,要需定义什么变量(当然那时候是没有接口的观点的)自己清晰的很。但是在现没有做系统的时候就要把这些都写出来。肯定是不能拿来原的系统作为参考的。那时的系统自己从来没有虑考什么定名范规三范式的。而且那时候更没有应用接口、设计模式。这让我怎么写呢。

        但是话说回来些档文的的目就是为了便利发开的。些档文和画uml图该应是要占个整发开过程80%的间时的。

        对于我这类刚体会了一点面向对象的想思的菜鸟说来,让我做到指挥若定,决胜千里。似乎有点难了。于是我胆大的决议,在档文只写到了概要设计的时候我开始了程编实现。

        

            从vbc#vb.net这个适度该应说是不大的。但做得真正的灵活运用还真多得捣腾几遍。开始用vb.net码编时总觉感不道知如何手下了。

        但几天的摸爬滚打总算实现了简略的登录。

        

        结总几个技巧要点值得注意。。

     

        1.Shared Static关键字:

        参考浏览:

        VB.net中shared和static关键字的区分密解

            其中vbstatic关键字的用作为:

        

            在类中的static成员变量意味着它为该类的有所实例所同享,也就是说当某个类的实例修改了该静态成员变量,其修改值为该类的其它有所实例所见;

        

            vb.netshared关键字的用作:

         

            同享类或结构的成员使每一个实例都可以应用该成员,而不是采取非同享模式,在非同享模式下,每一个实例都要需有自己的副本。例如,如果一个变量的值应用于个整应用程序,这点很有效。如果声明该变量为 Shared,那么有所实例会拜访雷同的存储位置,而如果一个实例更改了变量值,有所实例会都拜访更新后的值。

         

            由此可见vb.net中的shared关键字的用法和vbstatic的用法是雷同的。

         

            2.应用抽象工厂时提示:

        每日一道理
    青春,有嬉笑声与哭泣声夹杂的年华,青春的少年是蓝天中翱翔的幼鹰,虽然没有完全长大,有些稚气,有些懵懂,脱不开父母的双手却极力想去找寻属于自己的一片天空,为的是一时的激情,为的是一种独自翱翔的觉感!

      未能加载文件或程序集“”或它的某一个依附项。系统找不到指定的文件

            决解法方:

        

            按照三层的构架,是DALFactory程序集里通过反射创立针对特定数据拜访层里的对应类实例,这样BLL调用接口时就道知调用这个对应类实例里的实现法方 

        

            而反射动态加载程序集是通过这类法方 Assembly.Load("程序集").CreateInstance("定名空间."),其中的“程序集”读取的是Webbin文件夹下对应的dll,即反射加载的程序集dllUI层的bin文件夹必须有,不然就会涌现如题的误错。

        需只把DAL层的异变径路放到:UI层的bin文件夹。

        

        但这之前定一要证保一下几点:

        

                1.反射程编求要在网站的Bin文件夹中有经已译编好的.DLL文件(即持保DLL文件存在),并且持保称名和译编前库类的称名分歧。

        可称:加添引用性。

         

                2.查看网站中的目项(库类)性属,确认否是默许定名空间和程序集称名以及Bin文件夹下的DLL文件称名否是分歧,不分歧则会涌现未能加载文件或者程序集,所以的修改目项的性属。

        可称:称名分歧性。

         

                3.议建在程编的时在创立库类的时候写上系统称名+目项称名,可以有效的免避Bug产出。即:SystemName.Model或者SystemName.IDALegBBS.Model

        可称:称名完整性。

         

         Assembly.Load(path)其中这个path是加载你目项webbin目录的程序集,也就是说你要反射的程序集在你的UIbin下定一要有,看看你引用没有呢?

         

               4Model无引用。

         

               5DALFactory引用IDAL,通过读取web.config里设置的程序集,加载类的实例,返回给BLL应用。

         

               6SQLServerDAL引用 ModelIDAL,被DALFactory加载的程序集,实现接口里的法方。

         

        两个要主的问题。大家可能也会碰到。

        当然不止是这两个问题。而且后以的问题也定一很多。但代码是一点点写的不写是永久完不成的。想手动还没有手动重构的同窗希望对你们有助帮。

        

     

    文章结束给大家分享下程序员的一些笑话语录: 古鸽是一种搜索隐禽,在中国快绝迹了…初步的研究表明,古鸽的离去,很可能导致另一种长着熊爪,酷似古鸽,却又习性不同的猛禽类——犤毒鸟

    转载于:https://www.cnblogs.com/jiangu66/archive/2013/04/30/3052180.html

    展开全文
  • Paratune机群应用性能分析软件Paraview机群应用性能分析软件) Paratune软件介绍: Paratune用于分析Paramon生成的.para应用运行特征文件,显示应用运行时各结点中处理器、内存、网络和磁盘的性能数据,重构...
  • 软件工程(书第9版)》是系统介绍软件工程理论的经典教材,自1982年初版以来,随着软件工程学科的不断发展,不断更新版本,影响了一代又一代软件工程人才,对学科本身也产生了重大影响。本版保留了上一版中的软件...
  • 前后端界面也全面重构,更加简洁,规范和易用。开放全部源代码,并保留所有注释,可以在遵循开源协议的前提下,方便的进行二次开发,甚至可以基于术框架构架一个全新的系统,我们将来会提供详细的API文档。 1.最快捷,最...
  • 芭奇站群营销支持批量导出软件采集的文章到本地,批量导出软件伪原创后的文章到本地和批量边采集文章,边导出文章到本地,也支持把本地文章导入到站群里面,支持每个栏目导入一定数量的文章,也支持每个网站随机一...
  • 前后端界面也全面重构,更加简洁,规范和易用。开放全部源代码,并保留所有注释,可以在遵循开源协议的前提下,方便的进行二次开发,甚至可以基于术框架构架一个全新的系统,我们将来会提供详细的API文档。 1.最快捷,最...
  • 13、使用本软件编辑的图形可以按县界、乡界、村界、宗地界、国有界、界址点分层分类导入苍穹建库软件CAD中编辑的属性信息可完整输出,现在建库尚早,软件编写时仅实验性的导出了部分属性,用户可验证软件的功能...
  • UML和模式应用(书第3版)

    热门讨论 2013-06-20 00:33:37
    书名: Applying UML and Patterns : An Introduction to Object-Oriented Analysis and Design and Iterative Development (3rd Edition) 出版社: Prentice Hall PTR 作者: (美)Craig Larman 译者: ...
  • 同时,各种图像、音视频编辑软件的应用也变得非常普及,一方面人们可以享受到其带来的便利,但另一方面也使得对数字产品的内容进行篡改变得很容易。 为了解决这个问题,数字水印技术通过将一种不可见的标记嵌入到...
  • 《持续交付--发布可靠软件的系统方法》,英文名《Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation》,作者:(英)Jez Humble、(英)David Farley,翻译:乔梁,...
  • 信号系统课设

    2019-02-27 14:27:39
    本次课程设计应用MATLAB实现连续信号的采样,验证抽样定理以及与重构仿真,了解MATLAB软件,学习应用MATLAB软件的仿真技术。它主要侧重于某些理论知识的灵活运用,以及一些关键命令的掌握,理解,分析等。初步掌握...
  • 测试开发书籍推荐

    千次阅读 2013-11-03 10:52:10
    软件测试(书第2版) Ron Patton, 不多说,入门经典。 软件测试经验与教训 Cem Kaner,James Bach,Bret Pettichord ,更适合有经验的人看,看了少掉坑里。 xUnit测试模式--测试码重构  Gerard Meszaros 。本书...

    软件测试(原书第2版)

    Ron Patton, 不多说,入门经典。

    软件测试经验与教训

    Cem Kaner,James Bach,Bret Pettichord ,更适合有经验的人看,看了少掉坑里。

    xUnit测试模式--测试码重构 

    Gerard Meszaros 。本书获得2008年 Jolt Award技术图书类生产力大奖。

    探索式软件测试

    James A. Whittaker ,很有意思的一本书,freedom!

    赢在测试:中国软件测试先行者之道

    蔡为东,本土佳作,补充正能量。




    展开全文
  • 作为软件的基石,代码的质量决定了最终产品的质量,本书从这一点出发,介绍了高质量C#代码的成就过程,即从基础代码到软件结构,以及不断优化和重构的过程。本书主要内容包括C#的基本语法、结构与应用特点,常用开发...
  • ...其中第一部介绍的是把不同模式运用到不同的J2EE软件的层中,和一些基本的模式重构重构书籍《Refactoring Improving the Design of Existing Code》 其中这张图片代表着所有模式和层次间的...
  • 标题:想成为一个高薪的web前端工程师需要掌握哪些知识?Web前端开发是从网页制作演变而来的,名称上有很明显的时代特征。各种类似桌面软件的Web应用大量涌现,网站的前端由此发生了翻天覆地的变化。网页不再只是...
  • 女王大学计算学院的软件质量保证(CISC 327)2018年秋季课程分配是根据有意使用的钝化规范实施的两部分软件系统的实施。 最初使用本课程用Java完成该项目之后,在这里,我将在C#中重新实现它作为练习的机会。 目标 ...
  • SOLID 原则

    2013-08-05 09:33:00
    在21世纪的前几年里,“Uncle Bob”Robert Martin引入了用OOP开发软件的五条 则,其目的是设计出更易于维护的高质量系统。无论是设计新应用程序,还是重构现有基 本代码,这些SOLID原则都成为开发人员的地图。 ...
  • Bob”Robert Martin 引入了用OOP 开发软件的五条 则,其目的是设计出更易于维护的高质量系统。无论是设计新应用程序,还是重构现有基 本代码,这些 SOLID 原则都成为开发人员的地图。   1. 单一...
  • 2.选择一幅图像,对其进行离散Fourier变换,分别利用其相位谱,振幅谱重构原图像,比较实验结果;选择两幅不同类型的图像,分别进行Fourier变换,交换二者的相位谱后求反变换,比较实验结果,说明图像Fourier相位谱...
  • 6.2.4 全景 6.2.5 服务样例 6.3 另一个视图 6.4 结论 第7章 参考实现 7.1 为什么不用OSGi 7.2 这个练习的背景:构建系统 7.3 初始版本 7.4 第一次重构 7.5 第二次重构 7.6 第三次重构 7.7 第四次重构 7.7.1 关于...
  • 6.2.4 全景 6.2.5 服务样例 6.3 另一个视图 6.4 结论 第7章 参考实现 7.1 为什么不用OSGi 7.2 这个练习的背景:构建系统 7.3 初始版本 7.4 第一次重构 7.5 第二次重构 7.6 第三次重构 7.7 第四次重构 ...

空空如也

空空如也

1 2 3 4 5
收藏数 93
精华内容 37
关键字:

原图重构软件