设计模式(七大原则)理论知识

设计模式


使用场景


   软件架构和程序设计


目的


   1.提高代码的可重用性
   2.提高代码的可读性
   3.保障代码的可靠性


设计原则特点


   1.可扩展性(Extensibility) 
   2.灵活性(Flexibility) 
   3.组件化可插拔式(Pluggability)

准则

  • 单一职责原则:一个Java类存放的功能不能实现不同属性的功能,吃饭和睡觉这是两件事,需要分开创建对象。
class HandleUser{

    // 增删改查 操作用户 登录注册功能
    public User getUser(){};
    public void updateUser(int id){};
    public void saveUser(int id){};
    public void removeUser(int id){};

    // 用户玩游戏
    public void userPlayGame();

}

/**
 *
 * 这两个功能是不是不应该杂糅在一起,所以需要创建两个Java类,来存放不同功能
 *
 */

class UserHandleDao{

    // 增删改查 操作用户 登录注册功能
    public User getUser(){};
    public void updateUser(int id){};
    public void saveUser(int id){};
    public void removeUser(int id){};
}

class UserBusinessDao{

    // 用户玩游戏
    public void userPlayGame(){};

}
  • 开闭原则:软件对外的扩展开放,对外修改关闭,吃饭你得选择吧,有选择就有需求,有需求就有喜好,比如你喜欢吃西红柿,那么你还是需要品尝人间美食,没有吃过的食物自然需要你的尝试,才能确定好吃与否,但再好的美食也不会影响你原本喜好的美食,这是一样的道理。
class UserBusinessImpl{

    @注入
    private ConncetMouxinUtil;

    // 普通用户玩游戏 国王游戏
    public void ordinaryUserPlayGame(){};
    // VIP用户玩游戏
    public void VipUserPlayGame(){};

}

/**
 *
 * 用户玩本公司的游戏,以及登录注册游戏账号,但是呢大家都是有身份的人,怎么会没有某信账号
 * 什么?没有某信注册账号,对不起我不玩辣鸡游戏
 * 这时我们需要外接接口,挽救玩家
 *
 */
class ConncetMouxinUtil{

    // 软件的扩展,但是也拒绝其某信修改或者获取软件数据
    public void connectMouxin(){};    

}
  • 里氏代换原则:具备相同属性功能总结到一个父类,而子类继承父类属性和功能,打个比方,妈妈和女儿,爸爸和儿子,四人家庭,女儿和儿子都继承自爸爸和妈妈的优秀基因,自出生一刻,身材长相全都由父母提供,你也具备了和父母一样的寿命,思想,意识,智慧,全都继承自你的父母,当然人类还有很多不同属性,所以不能归纳到一个父类中,你的性格和未来发展等等。
class TravelerKong{

    // 技能:裂空之剑
    public void skillLiekongZhijian(String AKey){
        System.out.println("造成9999伤害!");
    }

}

class TravelerYing{

    // 技能:异邦铁风
    public void skillYibangTiefeng(String BKey){
        System.out.println("造成100000伤害!");
    }    

}

/**
 *
 * 你看空和荧的技能参数一样,功能也一样,只是输出不一样
 * 可要是每个人物都写这样无数的技能,维护和板砖都是极不友好
 * 平A你都要给写一个对象吗
 *
 */

class TravelerTian{

    // 技能:万物归一
    public void skillWanwuGuiyi(String AKey,String hurt){
           System.out.println(hurt);     
    }

}

class TravelerKong extends TravelerTian{

    @Override
    public void skillWanwuGuiyi(String AKey,String hurt){
         // 非空判断省略了
         if( AKey == KEY_FLG )
           System.out.println(hurt);     
    }

}

class TravelerYing extends TravelerTian{
    
    private static final String KEY_FLG = "1";


    @Override
    public void skillWanwuGuiyi(String AKey,String hurt){
         if( AKey == KEY_FLG )
           System.out.println(hurt);     
    }

}

class PersonageTest{

    private static final String KONG_HURT = "造成9999伤害!";

    private static final String YING_HURT = "造成100000伤害!";

    private static final String KEY_FLG = "1";
   
    @Test
    public void GameTest(){
        TravelerTian tk = new TravelerKong();
        // 某某调用了这个方法 判断省略了
        tk.skillWanwuGuiyi(parma , KONG_HURT);

        TravelerTian ty = new TravelerYing();
        // 某某调用了这个方法 判断省略了
        ty.skillWanwuGuiyi(parma , YING_HURT );
        
    }
    
}
  • 依赖倒转原则:面向接口编程,接口只是申明具体动作的别称,形容这是一个怎样的动作,所以不具备具体的发生动作的过程,想要真正描绘出动作的过程,此时,需要一个Java类实现implements某个动作别名的接口,举例来说,睡觉,坐着睡和躺着睡,坐着睡只是一个叫法,具体需要我们细致观察后,我葛优躺在一张长凳上睡着了,微张的小嘴发出轰隆隆的鼾声,哈喇子不争气的流了一条小河,这就是具体的坐着睡的行为描述,完整的将整个睡觉的动作具象化,躺着睡也是一样的情形。
class interface MyGame {
    
    void LOL();
    void YuanShen();
    void CF();
    void WangZheRongYang();
    .......

}

/**
 *
 * 接口只是一个万物的名字代称,不具备业务实现
 * 而我们将这类相同属性的事务,归纳到一个接口中,这就是我所理解的面向接口编程
 *
 */
class UserGame implements MyGame {
    
    // 接口需要全部实现方法
    public void  LOL(){};
    public void  YuanShen(){};
    public void  CF(){};
    public void  WangZheRongYang(){}; 

}
  • 接口隔离原则:相似的动作,处理数据行为,统一使用不同接口分别存放,类似于坐着睡、躺着睡这两个行为是一个动作,存放一个接口;而狼吞虎咽的吃饭,细嚼慢咽的品尝食物,又是一个动作,需要另一个接口存放。
class interface MyGame {
    
    void LOL();
    void YuanShen();
    void CF();
    void WangZheRongYang();

    void aOiSoLa();

}

/**
 *
 * aOiSoLa()这是什么鬼?你们细细品会,这两个东西当然不能放在一起,会出大事的!
 *
 */
  • 合成复用原则:在系统中尽量使用组合和聚合关联,少使用继承关系,会造成代码的耦合,很简单的讲,你和你哥们,会在一件认爹这事上达成事实吗?这时,我们就需要口头上事实,一口一口儿子的叫,但是儿子而不会真的认你当爹,真把你当爹了,随之就是多了个儿子,还要给儿子好处,那是万万不行的,儿子就是儿子,不应该要爹的好处,所以我们叫儿子的时候,一惯作风拿来用,跑腿去食堂带饭,都是儿子应该做到的。儿子相当于一个Java类,直接申明儿子对象,在后续方法中调用。
class TravelerTian{

    // 技能:万物归一
    public void skillWanwuGuiyi(String AKey,String hurt){
          System.out.println(hurt);    
    };

}

class TravelerKong extends TravelerTian{

      public void doRequest(){
        super.skillWanwuGuiyi("1","123");
    }

}

/**
 *
 * 某天你收到用户差评,要求你把钟离伤害拉高,糟糕的是,你写了继承关系
 * 该死,你必须要在父类中添加方法,可是一旦添加方法
 * 子类必须继承一个没有任何用处的方法,造成代码的耦合性
 * 为此,你必须将继承关系改写为组合关系
 * 正因为父类是抽象类
 *
 */
class TravelerKong {

    @注入
    private TravelerTian travelerTian;

    public void doRequest(){
        travelerTian.skillWanwuGuiyi("1","123");
    }

}
  • 迪米特法则:一个类减少其他类的业务,通过引入第三类调用该类的业务,要是一个人每天的日常全部编入程序,吃饭睡觉工作学习娱乐,这些每天都发生,可是又有点不同,你不可能将每天都总结在一个Java类中,那会有无数的Java类,这时你就需要把吃饭睡觉放入单独的Java类,完全独立的事件,吃饭是吃饭,睡觉是睡觉,你不能把这两件事混为一谈,所以他们自然成为两个对象,当需要汇总一天的事情时,主类才会调用这个对象,将对象属性重新定义睡觉的姿势,吃饭的过程。
    class MyWordGame {
    
        // 现实 虚拟 大脑
    
        // 游戏要远离现实世界
        public void fleeReality(){}
        
        // 游戏要进入虚拟世界
        public void entrySuppositional(){}
    
        // 大脑要分辨现实和虚拟
        public void brainDiscriminateRAE(){}
    }
    
    /**
     *
     * 仔细想想,这三个的关系,一定大脑在前,现实在后,虚拟在末尾
     * 三者不能同时进行,必定有多层处理,需要重新将包结构建立
     * 以前都是在同一个包内
     *
     */
    com.hikktn.reality
    com.hikktn.suppositional
    com.hikktn.brain
    
    继续进行业务细化
    
    com.hikktn.reality.service
    com.hikktn.reality.dao
    com.hikktn.reality.controller
    
    与此类推
    ……
    

猜你喜欢

转载自blog.csdn.net/qq_41520636/article/details/111189561