23种设计模式之策略模式,单例模式 ,工厂方法模式,抽象工厂模式,观察者模式

策略设计模式

what:概念

定义了算法族,分别封装起来,让他们之间可以互相替换,
此模式让算法的替换独立于使用算法的客户。
(这里的算法就是一个个行为-方法)

1. 继承的弊端

  • 首先使用继承来设计接口是一种很糟糕设计方法,因为软件总是存在变化的,使用继承很难应对改变,因为父类的改变会改变所有的子类

  • 在需求变化中,会出现并不是所有的子类都需要基类的方法,这样就违反类里氏代换原则。

2. 引子

  • 找出应用中可能需要变化之处,并将它独立出来,不要和那些不变化的代码混合在一起。

2.1 依赖倒转原则(针对接口编程真正的意义是针对超类型编程)

  • 所谓超类,我们常用的就是接口了,还有基类,抽象类。

  • 简而言之就是我实际操作是只操作这些超类,并不直接操作具体实现类。

2.1.1 个人理解
  • 设计中,要让设计更加有弹性。有弹性的前提是在一开始设计时就不要写死,留出更所的可变空间。面向接口编程刚好能提供这样的弹性空间。
  1. 提供弹性的很直观的方法就是组装一个类。和现实中的组装一样,一个牌子的电脑,显卡好但cup不好,主板好但内存差。反正就是不符合我们的要求。

  2. 那怎么办,我们可以自己买 主板 ,显示器,显卡,内存,主机来组装我们自己的电脑,这样就能满足我们的需求。

  3. 软件设计的装也一样,我们的材料就是接口了,通过使用不同的接口来组装我们的类。(接口:就相当于:主板,显示器…)(不同接口的实现类:相当于主板有不同厂家,显示器有三星,戴尔…)

  4. 还有最终要的一点,我们组装的类不实现任何接口,都是用每个接口的实现类来进行组装。(相当于富士康不造零件,它只搞组装一样)。不绑死才会更灵活,这样才会有弹性。

2.1.2 疑问

都说针对接口编程而不针对实现编程,但是有时候实现类会拓展接口的,导致接口实现类中的某些方法并不在接口中。这样就不能通过接口编程了,该如何解决这个问题呢?

2.1.3 关于组装的代码示例
  1. 接口组装
//鸭子接口
public interface Duck {
   
    public void swim();
    public void display();
}
//红色鸭子组装类
public class RedDuck implements Duck {
   
    public void swim() {
   
        System.out.println("是鸭子都会游泳!");
    }

    public void display() {
   
        System.out.println("我是红色的!");
    }
}

//蓝色鸭子组装类
public class BlueDuck implements Duck {
   
    public void swim() {
   
        System.out.println("所有鸭子都会游泳!");
    }

    public void display() {
   
       System.out.println("我是蓝色的!");
    }
}

//测试类
public class mainTest {
   
    public static void main(String[] args) {
   
        System.out.println("红色鸭子~~~~~~~~~~~");
        Duck duck= new RedDuck();
        duck.swim();
        duck.display();

        System.out.println("蓝色鸭子~~~~~~~~~~~");
        Duck duck1= new BlueDuck();
        duck1.swim();
        duck1.display();
    }
}

//运行结果
红色鸭子~~~~~~~~~~~
是鸭子都会游泳!
我是红色的!
蓝色鸭子~~~~~~~~~~~
所有鸭子都会游泳!
我是蓝色的!
  1. 继承
//颜色接口
public interface ChangeColor {
   
    public void color();
}

//颜色接口实现类01-红色
public class RedColor implements ChangeColor {
   
    public void color() {
   
        System.out.println("我是红色的!");
    }
}
//颜色接口黑色实现类
public class BlackColour implements ChangeColor {
   
    public void color() {
   
        System.out.println("我是黑色的!");
    }
}

//颜色接口实现类02-蓝色
public class BlueColou implements ChangeColor {
   
    public void color() {
   
        System.out.println("我是蓝色的!");
    }
}
//鸭子基类
public class Duck01 {
   
    //这里私有变量,子类是无法继承的
    public ChangeColor changeColor;
    public void swim() {
   
        System.out.println("所有鸭子都会游泳!");
    }
    //展示鸭子颜色
    public void performColor(){
   
        changeColor.color();
    }
    //改变颜色接口
    public void setClour(ChangeColor clour){
   
        changeColor=clour;
    }
}


//继承鸭子基类的黑鸭子
public class BlackDuck extends Duck01 {
   
    public BlackDuck() {
   
        changeColor= new BlackColour();
    }
}


//测试类
//将颜色的具体实现类注入到展示方法中,可以任意改变鸭子颜色,很灵活
 public class mainTest {
   
    public static void main(String[] args) {
   
        System.out.println("黑色鸭子~~~~~~~~~~~");
        Duck01 duck2= new BlackDuck();
        duck2.swim();
        duck2.performColor();
        //改变鸭子颜色
        duck2.setClour(new RedColor());
        duck2.performColor();
        
    }
}

//结果:
所有鸭子都会游泳!
我是黑色的!
鸭子换色~~~~~~~~~~~
我是红色的!
2.1.4 组装总结
  1. 该组装类中,颜色是用了接口+外部实现类来进行组装,通过提供的改变鸭子颜色方法,可以随意的改变鸭子的颜色,在改变颜色这里弹性高

  2. 继承的话,基类定义所有的鸭子都会游泳,但后期需求变更,加入了铁鸭子,铁鸭子不会游泳的。这就体现了继承的不足,要修改的话就要修改鸭子基类了,这又违背了里氏代换原则。

  3. 组装的疑问:是不是所有的方法都要定义单独的接口呢?其实不是的,只有哪些会发生变化的。

  4. 由上面代码可知,继承有很大的缺点,使用外部接口组合(组装)更具灵活性。这也体现多用组合,少用继承的设计原则

单例模式

个人理解

  • 单例模式如名字而言,就是该类只有一个示例对象。

why :为什么要使用单例模式

  • 使用单例模式,意味着只能有一个实例来提供服务。计算机中有的业务是必须只能有一个实例来的。

  • 如:网站计数,window系统的任务管理器,线程池,数据库的连接池。这些都是只允许一个实例存在

how :怎么实现单例模式

1. 单例模式结构

  • 单例类:实现创建唯一的实例,并提供使用该实例的接口方法。

你可能感兴趣的:(设计模式,设计模式,java,编程语言,面试,多线程)