设计原则
找出应用中可能需要的变化之处,把他们独立出来(封装),不要和哪些不需要变化的代码混在一起
实际举例
我们实现一个鸭子,且这个鸭子有很多种,且有各个属性。我们应该如何设计这个鸭子呢?首先鸭子不变的属性有哪些? 外观,游泳。等(先定义这两个)鸭子变的属性有哪些? 有的会叫,有的会飞等那我们怎么去定义 红鸭子,黑鸭子,还有玩具鸭子?
show me code
由于鸭子都会游泳和有外观,那么我们创建一个最基础的鸭子
package 设计模式;
/**
* @author yuanxindong
* @date 2020/7/4 12:38 上午
*/
public abstract class Duck {
/**
* 由于不是所有的外形都是一样的所以定义一个可以被实现外形的抽象方法
*/
public abstract void disPlay();
//所有的鸭子都会呱呱叫,所以这个行为可以放在基类里面,
// 由于有部分鸭子不会游泳所以不能写在基类上
// String quack() {
// return "呱呱挂";
// }
/**
* 所有的鸭子都能游泳
*
* @return
*/
String Swim() {
return "游泳ING";
}
}
刚开始我们使用抽象类,定义一个鸭子,且将有可能有不同的颜色的情况轻易为抽象方法,这个抽象方法可以起到一个约束的作用,意思也就是你是鸭子必须有外观。
package 设计模式;
/**
* @authoryuanxindong
* @date: 2020/7/4 12:57 上午
*/
public interface FlyAble {
void fly();
}
package 设计模式;
import io.netty.handler.codec.mqtt.MqttUnsubAckMessage;
/**
* @author yuanxindong
* @date 2020/7/4 12:58 上午
*/
public interface QuackAble {
void quack();
}
package 设计模式;
/**
* @authoryuanxindong
* @date: 2020/7/4 12:58 上午
*/
public interface SwingAble {
void Swing();
}
但是由于不同的鸭子有可能不会飞也不会叫如橡皮鸭,所以这种情况下,我们就得想法实现了,要么在实现的每个鸭子里面写下自己的属性。这样的花会产生大量的重复代码,所以我们可以通过接口定义,将几种行为方式起一个接口。继承整个接口且实现就可以轻松的展示自己的特点了。还有就是我们定义了接口后还会被其他的属性使用,比如狗也会叫等等。通过接口和抽象方式定义各个鸭子
package 设计模式;
/**
* @author yuanxindong
* @date 2020/7/4 12:43 上午
*/
public class BlackDuck extends Duck implements SwingAble{
/**
* 由于是继承于Duck的且duck是没有被实现的,所以duck必须要定义这个
* 这个约束让代码变得规范
*/
@Override
public void disPlay() {
System.out.println("我是一个黑鸭子");
}
@Override
public void Swing() {
System.out.println("游泳高手");
}
}
package 设计模式;
/**
* @author yuanxindong
* @date 2020/7/4 12:55 上午
*/
public class RubberDuck extends Duck implements SwingAble {
/**
* 这个鸭子只有外观
*/
@Override
public void disPlay() {
System.out.println("灰色");
}
@Override
public void Swing() {
System.out.println("游泳");
}
}
总结
在设计代码的时候:将不变的和经常变得代码分开。实现的方式:可以通过抽象类和接口的继承和实现的方式。
参考
《Head first 设计模式》
软件开发一个不变的真理:CHANGE