设计模式之七大原则

1.单一职责原则:

  •  不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责
  • 使用一个列子来表达,一个动物类,动物可以使用里面的方法进行奔跑:
//单一职责原则测试
public class SingleResponsibility {
    //举个列子
    public static void main(String[] args) {
        new Animal().run("老虎");
        new Animal().run("狮子");  
     //麻雀为什么能奔跑 错误
new Animal().run("麻雀"); } } //动物 class Animal{ // public void run(String name){ System.out.println(name+"森里里面奔跑"); } }

结果:
  • 老虎森里里面奔跑
  • 狮子森里里面奔跑
  • 麻雀森里里面奔跑

利用单一职责原则来设计:

//单一职责原则测试
public class SingleResponsibility {
    //举个列子
    public static void main(String[] args) {
        new LandAnimal().run("老虎");
        new LandAnimal().run("狮子");
        new FlightAnimal().run("麻雀");
    }

}
//陆地动物
class LandAnimal{
    //
    public void run(String name){
        System.out.println(name+"森里里面奔跑");
    }
}
//飞行动物
class FlightAnimal{
    //
    public void run(String name){
        System.out.println(name+"在天空飞翔");
    }
}
结果:
  • 老虎森里里面奔跑
  • 狮子森里里面奔跑
  • 麻雀在天空飞翔

2.接口隔离原则:

  • 一个类对另一个类的依赖应该建立在最小的接口上。
  • 举个列子,水果店和蔬菜店(没有使用之前)
package com.jie.sixprinciples;
//接口单一原则
public class SinglePrinciple {
    public static void main(String[] args) {
        new FruitStore().cutApple(new LiMaster());
        new FruitStore().cutTomato(new LiMaster());

        new VegetableShop().cutTomato(new LiuMaster());
        new VegetableShop().cutCabbage(new LiuMaster());

    }
}
//切菜接口
interface ChoppingVegetables{
    //切苹果
    void cutApple();
    //切番茄
    void cutTomato();
    //切白菜
    void cutCabbage();
}
//李师傅负责水果店
class LiMaster implements ChoppingVegetables{

    @Override
    public void cutApple() {
        System.out.println("李师傅切苹果");
    }

    @Override
    public void cutTomato() {
        System.out.println("李师傅切番茄");
    }

    @Override
    public void cutCabbage() {
        System.out.println("李师傅切白菜");
    }
}
class LiuMaster implements ChoppingVegetables{

    @Override
    public void cutApple() {
        System.out.println("刘师傅切苹果");
    }

    @Override
    public void cutTomato() {
        System.out.println("刘师傅切番茄");
    }

    @Override
    public void cutCabbage() {
        System.out.println("刘师傅切白菜");
    }
}
//水果店
class FruitStore{

    public void cutApple(LiMaster liMaster) {
       liMaster.cutApple();
    }


    public void cutTomato(LiMaster liMaster) {
     liMaster.cutTomato();
    }


    public void cutCabbage(LiMaster liMaster) {
    liMaster.cutCabbage();
    }
}
//蔬菜店
class VegetableShop{


    public void cutApple(LiuMaster master) {
        master.cutApple();
    }


    public void cutTomato(LiuMaster master) {
       master.cutTomato();
    }

    public void cutCabbage(LiuMaster master) {
        master.cutCabbage();
    }
}
结果:
  • 李师傅切苹果
  • 李师傅切番茄
  • 刘师傅切番茄
  • 刘师傅切白菜

使用接口隔离原则后:

package com.jie.sixprinciples;
//接口单一原则
public class SinglePrinciple {
    public static void main(String[] args) {
        new FruitStore().cutApple(new LiMaster());
        new FruitStore().cutTomato(new LiMaster());

        new VegetableShop().cutTomato(new LiuMaster());
        new VegetableShop().cutCabbage(new LiuMaster());

    }
}
//切菜接口

//切苹果
interface CutApple{
    //切苹果
    void cutApple();
}
//切番茄
interface CutTomato{

    //切番茄
    void cutTomato();
}
//切白菜
interface CutCabbage{
    //切白菜
    void cutCabbage();
}

//李师傅负责水果店
class LiMaster implements CutApple,CutTomato{

    @Override
    public void cutApple() {
        System.out.println("李师傅切苹果");
    }

    @Override
    public void cutTomato() {
        System.out.println("李师傅切番茄");
    }

}
class LiuMaster implements CutTomato,CutCabbage{

    @Override
    public void cutTomato() {
        System.out.println("刘师傅切番茄");
    }

    @Override
    public void cutCabbage() {
        System.out.println("刘师傅切白菜");
    }
}
//水果店
class FruitStore{
    public void cutApple(LiMaster liMaster) {
       liMaster.cutApple();
    }

    public void cutTomato(LiMaster liMaster) {
     liMaster.cutTomato();
    }

}
//蔬菜店
class VegetableShop{
    public void cutTomato(LiuMaster master) {
       master.cutTomato();
    }

    public void cutCabbage(LiuMaster master) {
        master.cutCabbage();
    }
}

 3.依赖倒转原则:

  • 高层模块不应该依赖低层模块,两者都应该依赖其抽象
  • 抽象不应该依赖细节,细节应该依赖抽象
  • 要面向接口编程,不要面向实现编程
  • 举个列子:给QQ发消息:
//依赖倒转列子 没有使用依赖倒置会显得很臃肿 如果想加一个微信 则还需要自动扩展方法等
public class RelyReverse {
    public static void main(String[] args) {
        new Message().chat(new Chatqq());
    }
}
//QQ
class Chatqq{
    //聊天方法
    public void chat(){
        System.out.println("qq在聊天");
    }
}
//消息类
class Message{
    public void chat(Chatqq qq){
        qq.chat();
    }
}
输出: qq在聊天

使用依赖倒转后:

//依赖倒转列子
public class RelyReverse {
    public static void main(String[] args) {
        new Message().chat(new Chatqq());
        new Message().chat(new ChatWechat());
    }
}
//定义一个接口方法
interface IMessage{
    void chat();
}
//QQ
class Chatqq implements IMessage{
    //聊天方法
    @Override
    public void chat(){
        System.out.println("qq在聊天");
    }
}
//微信
class ChatWechat implements IMessage{

    @Override
    public void chat() {
        System.out.println("微信在聊天");
    }
}
//消息类
class Message{
    public void chat(IMessage iMessage){
        iMessage.chat();
    }
}
输出:

  qq在聊天
  微信在聊天


使用依赖倒转三种传递方式:

  1. 接口传递:
    //通过接口来传递
    interface InMessage{
        void getMessage(Produce produce);
    }
    //生产者
    interface Produce{
        void getMessage();
    }
    class MessageTest implements InMessage{
        @Override
        public void getMessage(Produce produce) {
            produce.getMessage();
        }
    }

     

  2. 通过构造器来进行传递:
    //通过构造器来传递
    interface InMessage{
        void getMessage();
    }
    
    interface Produce{
        void getMessage();
    }
    class MessageTest implements InMessage{
        public Produce produce;
        public MessageTest(Produce produce){
            this.produce=produce;
        }
        @Override
        public void getMessage() {
            this.produce.getMessage();
        }
    }

     

  3. 通过set方法来进行:
    //通过set()方法来传递 
    interface InMessage{
        void getMessage();
    }
    
    interface Produce{
        void getMessage();
    }
    class MessageTest implements InMessage{
        public Produce produce;
        public void setProduce(Produce produce){
           this.produce=produce;
        }
        @Override
        public void getMessage() {
            this.produce.getMessage();
        }
    }

     

4.里氏替换原则:

  • 子类可以扩展父类的功能,但不能改变父类原有的功能
  • 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法
  • 子类中可以增加自己特有的方法
  • 举一个列子:计算器的加减:
  • //里氏替换原则
    public class Replace {
        public static void main(String[] args) {
            int add = new Caculator().add(5, 2);
            System.out.println("计算机加为"+add);
            int delect = new ChildCaculator().delect(5, 3);
            //应该为92 为什么为82 因为子类无意间扩展父类方法时破坏了方法需求
            System.out.println("扩展的减为"+delect);
        }
    }
    //计算器 加减功能
    class Caculator{
        public int add(int a,int b){
            return a+b;
        }
        //
        public int delect(int a,int b){
            return a-b;
        }
    }
    //加强版
    class ChildCaculator extends Caculator{
        //扩展 a+b后继续加10、
        public int add(int a,int b){
            return a+b+10;
        }
        //减与100求差
        public int delect(int a,int b){
            int add = add(a, b);
            return add-100;
        }
    }

    使用里氏替换原则:

  • class Fater{
    
    }
    //计算器 加减功能
    class Caculator extends Fater{
        public int add(int a,int b){
            return a+b;
        }
        //
        public int delect(int a,int b){
            return a-b;
        }
    }
    //加强版
    class ChildCaculator extends Fater{
        //使用属性的方式来调用
        private Caculator caculator=new Caculator();
        //扩展 a+b后继续加10、
        public int add(int a,int b){
            return a+b+10;
        }
        //减与100求差
        public int delect(int a,int b){
            int add = caculator.add(a, b);
            return add-100;
        }
    }

     

5.开闭原则:

  • 对扩展开发,对修改关闭
  • 如果软件需要改变功能应该是扩展而不是修改
  • 列子:绘制图形:
    //开闭原则
    public class OcpDemo {
        public static void main(String[] args) {
                new Grapi().draw(new Round());
                new Grapi().draw(new Square());
    
        }
    }
    //绘制类
    class Grapi{
    
        public void draw(Shape s){
            if (s.shapes==1){
                round(s);
            }else if (s.shapes==2){
                squar(s);
            }
        }
        //圆形
        public void round(Shape s){
            System.out.println("正在绘制圆形");
        }
        //绘制正方形
        public void squar(Shape s){
            System.out.println("正在绘制正方形");
        }
    }
    //形状类
    class Shape{
        int shapes;
    }
    //圆形
    class Round extends Shape{
        public Round() {
            super.shapes=1;
        }
    }
    //正方形
    class Square extends Shape{
        public Square() {
            super.shapes=2;
        }
    }

6.迪米特法则:

  • 一个对象应该对其他对象保持最少的了解
  • 类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。
  • 举个例子:总部和学院的人员:
    package com.jie.sixprinciples;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class DiMiTieDome {
        public static void main(String[] args) {
            new WordHeadQuartersTest().list(new WordPersonTest());
        }
    }
    
    //学院员工
    class WordPerson {
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        private String id;
    
    }
    
    
    //总部员工
    class WordHeadQuarters {
        private String id;
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    }
    //总部学院管理类
    class WordHeadQuartersTest{
        //存10个
        public List<WordHeadQuarters> add(){
            ArrayList<WordHeadQuarters> wordHeadQuarters = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                WordHeadQuarters wordHeadQuarters1 = new WordHeadQuarters();
                wordHeadQuarters1.setId("总部第"+i+"号人员");
                wordHeadQuarters.add(wordHeadQuarters1);
            }
            return wordHeadQuarters;
        }
        public void list(WordPersonTest wordPersonTest){
            for (WordHeadQuarters wordHeadQuarters : this.add()) {
                System.out.println(wordHeadQuarters.getId());
            }
            System.out.println("........");
            for (WordPerson wordPerson : wordPersonTest.add()) {
                System.out.println(wordPerson.getId());
            }
        }
    }
    //学院管理类
    class WordPersonTest{
        //存10个
        public List<WordPerson> add(){
            ArrayList<WordPerson> people = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                WordPerson wordHeadQuarters1 = new WordPerson();
                wordHeadQuarters1.setId("学院第"+i+"号人员");
                people.add(wordHeadQuarters1);
            }
            return people;
        }
    }

    使用迪米特法则后:降低类之间的关系

  • //总部学院管理类
    class WordHeadQuartersTest{
        //存10个
        public List<WordHeadQuarters> add(){
            ArrayList<WordHeadQuarters> wordHeadQuarters = new ArrayList<>();
            for (int i = 1; i < 10; i++) {
                WordHeadQuarters wordHeadQuarters1 = new WordHeadQuarters();
                wordHeadQuarters1.setId("总部第"+i+"号人员");
                wordHeadQuarters.add(wordHeadQuarters1);
            }
            return wordHeadQuarters;
        }
        public void list(WordPersonTest wordPersonTest){
            for (WordHeadQuarters wordHeadQuarters : this.add()) {
                System.out.println(wordHeadQuarters.getId());
            }
            System.out.println("........");
        wordPersonTest.list();
        }
    }
    //学院管理类
    class WordPersonTest{
        //存10个
        public List<WordPerson> add(){
            ArrayList<WordPerson> people = new ArrayList<>();
            for (int i = 1; i < 10; i++) {
                WordPerson wordHeadQuarters1 = new WordPerson();
                wordHeadQuarters1.setId("学院第"+i+"号人员");
                people.add(wordHeadQuarters1);
            }
            return people;
        }
        public void list(){
            for (WordPerson wordPerson : this.add()) {
                System.out.println(wordPerson.getId());
            }
        }
    }

     7.合成复用原则(Interface Segregation Principle,ISP)

  • 它要求在软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。

  • 合成复用原则是通过将已有的对象纳入新对象中,作为新对象的成员对象来实现的,新对象可以调用已有对象的功能,从而达到复用。
  • 如果要使用继承关系,则必须严格遵循里氏替换原则。

 

posted @ 2021-09-24 19:18  小杰i  阅读(66)  评论(0编辑  收藏  举报