如何利用面向对象的五大原则,将简单的代码复杂化

        某年某月的某一天公司业务扩大,接了个大项目。好了,产品经理又来了,哈哈哈哈,他说想要你实现一个界面展示界面,每次下拉刷新页面,然后你就开始埋头码代码,先是搞了一个叫请求的接口来管理网络请求和刷新界面,然后在model实现这个接口,三下五除二就把这个简单的功能给KO掉。心情美美的下班了。

public interface Request {

    void requestResource();

    void requestFailed();

    void requestSuccess();

    void updateView();

}

public class RequestModel implements Request{

    @Override

    public void requestResource() {

    //downLoad Resource

    }

@Override

public void requestFailed() {

}

    @Override

    public void requestSuccess() {

    updateView();

    }

    @Override

    public void updateView() {

    //update view

    }

}

        第二天上班,烦人的产品经理又来了,他说现在有一个新需求,用户可以下载自己喜欢的相关资源,图片文字等资源用户可以直接下载到本地,但是下载好的录音类资源只能在app中查看。你心想网络请求接口已经写好,那简单,开始继续埋头码代码,然后你发现,现在只需要下载功能就好了,不需要更新界面,这个时候去实现这个接口,会有一个多余的方法,不想出现这个方法就只能修改接口,网络请求在开发过程中跟很多功能都息息相关,所以你开始修改接口,幸好是项目刚开始,不然修改接口将是灾难性的,你开始思考怎么改,发现更新界面是一个职能,另外三个是一个职能,所以将现在的接口拆分成两个不同职能的接口,拆分完的两个接口,每个只负责自己相关的职能(单一职责原则【应该有且仅有一个原因引起类的变更,也就是接口或类和职责的关系是一一对应的】接口隔离原则【使用多个专门的接口比使用单一的总接口要好】

public interface Request {

    void requestResource();

    void requestFailed();

    void requestSuccess();

}

public interface View {

    void updateView();

}

原来实现一个接口改为实现两个接口

public class RequestModel implements Request,View{ ... }

//用户下载资源

public class DownLoadModel implements NetRequest {

    @Override

    public void requestResource() {

    //下载资源

    }

    @Override

    public void requestFailed() { }

    @Override

    public void requestSuccess(){}

}

        下载的功能实现后,我们来啃掉文件存储的骨头,图片和文字资源要给用户拿得到,所以要放在外部储存,语音资源要放在内部存储

public class SDStorage {

    void save(Object media){

    //文件储存在内存卡

    }

}

public class InternalStrorage{

    void save(Object media){

    //文件储存在数据库

    }

}

public class StroageManager {

    public static final int STROAGE_INTERNAL= 1;   

    public static final int STROAGE_SD = 2;

    public Object media;

    private int type = 1; 

    public StroageManager(Object media) {

        this.media = media;

    }

    public void setStroageType(int type) {

        this.type = type;

    }

    public void setMedia(Object media) {

        this.media = media;

    }

    public void save() {

        switch (type) {

            case STROAGE_INTERNAL:

                new InternalStrorage().save(media);

                break;

            case STROAGE_SD:

                new SDStorage().save(media);

                break;

        }

    }

}

        产品经理觉得两种方式不够,还应该增加数据库储存的方式,然后你就在心里骂他,fuck,就不能一次性把需求讲完么,你知道骂完也无济于事,好吧,接着搞,不就是搞多一个类嘛。那还不是小Case。又搞了个SQL数据库的。

public class SqlStorage {

    void save(Object media){

        //文件储存在数据库

    }

}

然后增加了标志位,和修改了save方法

public class StroageManager {

    ...

    public static final int STROAGE_SQL = 3;

    ...

     public void save() {

         switch (type) {

            case STROAGE_SD:

                new SDStorage().save(media);

                break;

            case STROAGE_INTERNAL:

                new InternalStrorage().save(media);

                break;

              case STROAGE_SQL: 

               new SqlStorage().save(media);

                break;

        }

    }

}

        改完后,你感觉增加一种存储方式,修改很麻烦,要改这么多地方,要是以后还有其他五花八门的储存方式,那岂不是要一直改改改,除了增加功能类外,还要增加n多个标志位,n多个switch case,反正大家都是调用同一个save方法。能不能搞一搞其他方式,增加新功能只需要增加功能类就可以呢。好了开试,首先大家方法都一样,那肯定是提取出来嘛。那我们先搞个接口。因为以后其他功能说不定也有保存的功能需要实现这个接口,调用其他保存方式,可能是保存在内存什么的,就叫资源存储吧。

public interface ResourceStroage {

    void save(Object media);

}

然后,刚刚的三个类就去实现这个借口。

public class SqlStorage implements ResourceStroage { ... }

public class SDStorage implements ResourceStroage { ... }

public class InternalStrorage implements ResourceStroage { ... }

接着修改StroageManager

public class StroageManager {

    private ResourceStroage resourceStroage;

    public StroageManager(ResourceStroage resourceStroage){//依赖注入

        this.resourceStroage = resourceStroage;

    }

    public void setResourceStroage(ResourceStroage resourceStroage) {

        this.resourceStroage = resourceStroage;

    }

    public void save(Object media) {

        resourceStroage.save(media);

    }

}

//调用的方式

new StroageManager(new SqlStorage()).save(media);

new StroageManager(new SDStorage()).save(media);

new StroageManager(new InternalStrorage()).save(media);

假设又有了一个新的存储方式,叫OtherStroage

public class OtherStroage implements ResourceStroage { ... }

//调用

new StroageManager(new OtherStroage()).save(media);

这样子,以后产品经理又要增加新的存储方式,只需要直接拓展就可以了。前面的实现方式,一旦有新增的方式,就要改动原先StroageManager代码,这样设计是很不合理的。相比较之下,改动后的实现方式就显的优雅多了,只关心拓展。(开闭原则一个软件实体如类、模块和函数应该对扩展开放,对修改关闭】、 依赖倒置【A.高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。 B.抽象不应该依赖于具体实现,具体实现应该依赖于抽象。以及 里氏替换原则【在软件中将一个基类对象替换成它的子类对象,程序将不会产生任何错误和异常,反过来则不成立,如果一个软件实体使用的是一个子类对象的话,那么它不一定能够使用基类对象。】

跟产品经理的梁子到这里就先告一段落啦,有时间会说到如何写出完全反五大原则,将代码简单化 哈哈哈

附上一部分资料:

https://www.jianshu.com/p/a7dc2e007d76

https://www.cnblogs.com/cody1988/archive/2012/06/05/2536254.html

https://blog.csdn.net/wzlyd1/article/details/50970635

http://www.supmen.com/r1qmn0dvzy.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342