博文

目前显示的是 五月, 2019的博文

设计模式-建造者模式

图片
        建造者模式,又叫构建者模式,构建器模式等等,定义这里我就不赘述了,网上书上都很多,可以很方便找来看。我为什么不说一遍呢,第一,觉得大部分的定义都描述的不是很易懂,第二,我自己目前还没达到能够下定义的水平。         先来看看代码,然后再给出我的理解。 public class Article { private String title ; private String content ; private String sign ; private Date time ; //省略了getter,setter,toString } public interface ArticleBuilder { void setTitle (String title) ; void buildContent (String title) ; void setTime (Date date) ; Article getResultArticle () ; } public class ConcreteArticleBuilder implements ArticleBuilder { private Article article = new Article() ; @Override public void setTitle (String title) { article .setTitle(title) ; } @Override public void buildContent (String content) { article .setContent(content) ; } @Override public void setTime (Date date) { article .setTime(date) ; } @Override public Article getResultArticl...

设计模式-抽象工厂

图片
        工厂方法模式中,工厂类用于生成一系列对象实例并且以这些对象的父级类型作为返回结果。当有多个这样的工厂,这些工厂之间会生产出一系列不同的对象,这种情况下,我们可以定义一个抽象工厂来描述工厂的行为,即创建一系列对象的方法,再让具体的工厂类继承这个抽象工厂。也可以说是把一个系列的工作抽象出来一个抽象的类型,这个抽象的类型就是抽象工厂。 先来看一下结构图: 下面来看一下具体代码: 定义抽象类型 public interface Animal { void say () ; } public interface Cat extends Animal { } public interface Dog extends Animal { } public interface Duck extends Animal { } 定义抽象工厂接口 public interface AnimalFactory { /** * 抽象工厂方法 * 特点与工厂方法一致: * 创建了一个对象 * 返回类型为一个接口或者抽象类 * 有多个类实现了上述抽象类型 * * @param animalType * @return */ Animal getAnimal (String animalType) ; } 抽象类型的具体类与具体工厂类(US) public class CatUs implements Cat { @Override public void say () { System. out .println( "america cat" ) ; } } public class DogUs implements Dog { @Override public void say () { System. out .println( "america dog" ) ; } } public class DuckUs implements Duck { @Override public...

设计模式-工厂模式

图片
    工厂模式,也叫工厂方法模式,定义一个用于创建对象的接口,可以控制对哪个类进行实例化 public interface Animal { void say(); } public class Cat implements Animal { @Override public void say() { System.out.println("miao miao miao"); } } public class Dog implements Animal { @Override public void say() { System.out.println("wang wang wang"); } } public class Duck implements Animal { @Override public void say() { System.out.println("ga ga ga"); } } public class AnimalFactory { /** * 此方法为工厂方法模式, * 特点为: * 创建了一个对象 * 返回类型为一个接口或者抽象类 * 有多个类实现了上述抽象类型 * @param color * @return */ public Animal getAnimal(String color) { if ("dog".equals(color)) { return new Dog(); } else if ("cat".equals(color)) { return new Cat(); } else if ("duck".equals(color)) { return new Duck(); ...

关于“复用”的一点想法

       关于复用,如何合理的复用这个事,想说清楚,真不是那么容易的事情,下面我说一个表是否复用的大致场景,以及我的感想。 有一个现有的表,然后有一个新业务,这个新业务和原来的表对应的业务很像(可想象空间很大), 那应该不应该复用,这里可能很难下定论,因为不知道这两个业务在长远看来是否是有共性,是否是可合并的,是否是互斥的,等等因素 如果仅仅是为了少建表这一个原因的复用,那么我认为是不可取的,这种情况下,可能表的字段满足当前的需求,但字段意义是有着千差万别的 很多情况下,为了区分这两个业务,可能会用type这类字段来区分一下,然后很大概率可能发生的情况是某一个业务需要调整,增加了一个字段,这时候另一个业务是完全不需要的,长此以往,可想而知这个表将来是什么样子,至少我看到这个表,以及对应的多个业务,是想吐的。 当然也有可能在刚开始复用的时候,是判断不出后面是这样的场景,那么在扩展表的时候,就需要有一定的决断力,表该拆的时候,一定要拆,不要为了省事,凑合着用。 往往实际开发的时候,不是这样,拆分可能会带来额外的工作量以及风险,工作量会因人而异,如果代码质量好,拆分的工作量可能会低些,然后另一个大家都不愿意触碰的是风险,如果因这些改动而造成了一些问题,那这个问题谁来担,公司中因为这个因素,使得大家几乎没有任何动力去优化当前现有的难看的代码,除非是公司文化使然,或者是领导明确了优化范围以及提供相应的测试资源,明确了此次需求的责任人,把这个事当成一个项目去做,可是,这样不对么?对么? 就我的意愿来说,我是希望在每次开发迭代中,把重构放第一位,从整体到局部,这样来说,是否复用的问题就变成如何设计当前的项目问题了。 可是反过来我又问自己,多出来的时间怎么办?风险谁来把控? 我自己尝试着回答,如果从长期来看,在一直保持着持续重构的基础之上,每次多出来的时间与风险,是完全可以抵消下一次迭代的开发周期节约的时间成本以及后期查问题的维护成本, 这个收益是延迟的,而且在一个本来就很乱的基础之上,首次做重构的工作,是很难的,如果后期不能持续这个传统,那么这一次艰难的重构工作会变得费力不讨好的事情。 还有一个点是,在重构的过程,最好是相关的业务人一起讨论,产品或者功能的性质,以后的演变的可能性,技术实...

设计模式-单例模式

        设计模式,通常指GOF的《 设计模式 可复用面向对象软件的基础 》书中提到的面向对象编程23种设计模式,话不多说,先来看一个单例模式。 单例模式,可以保证在系统中单例类只能有一个实例。 接下来我把在网上流行的大部分实现方案以及个人在思考单例模式的实现过程整理如下 方案一: /** * 饿汉式 * 使用时直接使用静态变量,理念不好,不利于扩展 */ public class Singleton { /** * 初始化动作写到静态代码块中是一样的效果 */ public static Singleton instance = new Singleton(); private Singleton() { } } 方案二: /** * 饿汉式 * 使用时调用 getInstance 方法,后期如有需求可直接改动方法实现即可 */ public class Singleton { public static Singleton instance = new Singleton(); private Singleton() { } public static Singleton getInstance() { return instance; } } 方案三: /** * 懒汉式,使用时才初始化 * 线程不安全,单线程环境下可用 */ public class Singleton { public static Singleton instance = null; private Singleton() { } public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }   方案四: /** * 懒汉式,使用时才初始化 * 线程安全,方法加锁,效率低 *...

排序算法演示动画

图片
        写前面两篇排序的时候,百度找图片,看到还比较不错的动图,能够展示数据在内存中的变化。然而性格使然,我会仔细的观察动图,仔细观察的话发现要么是无法较好的展示比较过程,要么是交换的过程与实际代码执行的有一些出入,心想自己做一个效果出来。这一想不要紧,4月30号-5月4号,花了几个晚上时间,终于搞定了俩算法的排序效果动图,这效率低的也是没谁了。 中间的尝试过程,以及遇到的问题, 1,开始用JavaScriptr的canvas,画出了初始化的状态,做到动效觉得会很麻烦,卡住了。 2,咨询前端同事,建议用css,于是改用div,做到动效的时候,仍然卡住,原因是延迟函数执行的效果和预期不一致,大致能猜到js的闭包特性导致。 3,于是想到用Java的canvas直接画出来,于是乎动手,写到动效,又卡住,动效过程中及时渲染没搞定,无奈对API不熟悉,暂时放弃。 4,重新思考div方案中遇到的问题的解决办法,按说,仔细处理一下延迟方法,应该可行,于是再次动手,这次把冒泡的效果做出来了,想着没问题了,接着套入插入排序,然而执行效果又与预期不一致,究其原因发现插入排序中多了break导致,break无法让事先定时的timer取消往下执行,这下又卡住了,带着问题入睡。 5,早上再继续,想到把排序过程和效果分开来写(最开始就是分开写的,过程中觉得直接一边排序一边展示效果更合理,然而后来证明,分开也有分开的好处),这下可以了。 中间遇到问题原因之一是对前端展示部分的代码熟悉程度不够,二是没有整体从开始思考可行的方案,也是因对前端代码的评估过于简单了,只在脑海中想了一下,就觉得没问题。JS的canvas,CSS的动画,Java的Canvas,应该都能实现该效果,这里暂且不深究了,本来的目的也只是想在做排序的时候,可以做出辅助理解的动画效果。 冒泡排序 https://github.com/angelala00/learn/blob/master/src/main/html/sort/bubblesort.html 插入排序 https://github.com/angelala00/learn/blob/master/src/main/html/sort/insertionsort.html ...