写在前面:
我是「境里婆娑」。我还是从前那个少年,没有一丝丝改变,时间只不过是考验,种在心中信念丝毫未减,眼前这个少年,还是最初那张脸,面前再多艰险不退却。
写博客的目的就是分享给大家一起学习交流,如果您对 Java感兴趣,可以关注我,我们一起学习
前言:学习完这篇文章你将对设计模式有了初步认识,运用好设计模式将对我们写代码达到事半功倍的效果。
一、模拟生产玩具车
1、玩具车超类
小张在一家设计玩具车公司上班,能设计出各种各样的玩具车,。此系统的内部设计使用了标准的OO技术,设计了一个玩具车超类(SuperCar),并让各种玩具车继承此超类。
2、让玩具车动起来
由于玩具车生产出来卖的非常好,现在领导要求玩具车要有动力,小张说这个好办,于是就在Car类上加了一个充电方法charge(),过了几天领导又有了新想法,我们以后还要能生产出可以加油的玩具车,小张听完说这个也好办,于是在Car类上又加了一个加油方法refuel()。但是问题来了一个子类继承Car父类两个方法都需要实现。我只想生产加油的玩具车,那么充电这个方法我就要覆盖掉,反之一样,对后面的维护工作更是噩梦,如果父类方法稍作修改,那所有的子类都需要跟着改,于是领导拍这桌子问小张你设计的是什么垃圾玩意,给你两天时间把这个需求设计的灵活点,否则下周就不要来上班了。所谓的灵活就是,要么生产充电的玩具车,要么生产加油的玩具车。
不管你在何处工作,构建些什么,用何种编程语言,在软件开发上,一直伴随你的那个不变真理就是需求一直在变。不管当初软件设计得多好,一段时间之后,总是需要成长与改变,否则软件就会“死亡”。
于是小张开始查资料,研究如何设计出好的代码,最后查出的原则是,
找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
换句话说,如果每次新的需求一来,都会使某方面的代码发生变化,那么你就可以确定,这部分的代码需要被抽出来,和其他稳定的代码有所区分。
下面是这个原则的另一种思考方式:“把会变化的部分取出并封装起来,以便以后可以轻易地改动或扩充此部分,而不影响不需要变化的其他部分”。
这样的概念很简单,几乎是每个设计模式背后的精神所在。所有的模式都提供了一套方法让“系统中的某部分改变不会影响其他部分”。
3、设计玩具车的行为
我们知道Car类内的refuel()和charge()会随着玩具车的不同而改变。为了要把这两个行为从Car类中分开,我们将把它们从Car类中取出来,建立一组新类来代表每个行为。
- ChargeCar 充电行为
public interface ChargeCar {
void charge();
}
- RefuelCar 加油行为
public interface RefuelCar {
//加油
void refuel();
}
4、实现玩具车的行为
在此,我们有两个接口,ChargeCar 和RefuelCar ,还有它们对应的
类,负责实现具体的行为。
这样的设计, 可以让充电和加油的动作被其他的对象复用,因为这些行为已经与Car类无关了。而我们可以新增一些行为, 不会影响到既有的行为类,也不会影响“使用”到加油或充电行为的Car类。
5、整合玩具车的行为
关键在于,Car现在会将充电和加油的动作“委托”(delegate)别人处理,而不是使用定义在Car类(或子类)内的充电和加油方法。
1、首先,在Car类中“加入两个实例变量”,分别为“chargeCar”与“refuelCar”,声明为接口类型(而不是具体类实现类型),每个Car对象都会动态地设置这些变量以在运行时引用正确的行为类型。
我们也必须将Car类与其所有子类中的charge()与refuel()删除,因为这些行为已经被搬到ChargeCar与RefuelCar类中了。
我们用两个相似的方法performCharge()和performRefuel()取代Car类中charge()与refuel()。
设计完之后Car类最终态为:
public abstract class Car {
private ChargeCar chargeCar;
private RefuelCar refuelCar;
public void setChargeCar(ChargeCar chargeCar) {
this.chargeCar = chargeCar;
}
public void setRefuelCar(RefuelCar refuelCar) {
this.refuelCar = refuelCar;
}
public abstract void brand();
public void performRefuel() {
refuelCar.refuel();
}
public void performCharge() {
chargeCar.charge();
}
public void carDoor() {
}
public void wheelHub() {
}
public void color() {
}
}
以上就是我们设计模式的入门,希望大家能看懂并且仔细揣摩其中的设计原理。找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。