设计模式--无模式

搞开发几年了,深深的明白设计模式的重要性,但是确不能真正彻底的运用自如;纵观现实生活中,比比皆是设计模式的最佳实践,比如:

在家里边墙面上的插座,一般都是扁孔的;自从买了一个港版的iphone后,竟然无法愉快的充电了,需要买一个转接头插在墙面的插座上才行,其实买的那个转换头就是充当一个适配器的作用,那么我们可以把这个实践称做–适配器模式

拿平时开的车来讲,你在北京买的车的生产厂家可能是河北制造的,你在南阳买的车的生产厂家可能是武汉制造的,但是有没有想过,同一款车的构件都是一样的,那么河北制造厂和武汉制造厂难道是全车所有配件都自己生产吗,那肯定不是的,与其称他们为制造厂,不如称他们为装配厂,因为汽车构件一般都有一个类似中央工厂的地方生产的,然后运输到各个装配厂进行组装成为整车!各个装备厂不需要关注发动机、轮胎是如何生产的,只需要把相应的部件进行组装成整车就行了,那么我们可以把这个实践称作–工程方法模式

1、第一代鸭子

有一个玩具公司主要生产一款明星产品“橡皮鸭”;橡皮鸭要求会呱呱叫、会游泳,但是他们的外观有多种,比如红色、黄色、黑色的;通过需求可以梳理以下内容:

每一种鸭子都会呱呱叫、都会游泳

鸭子可能有红色、黄色、黑色的外观

好了,我们下面定义父类Duck,并且定义三个方法:呱呱叫-quack、游泳-swim、外观-display;

1.1、定义父类-Duck

因为所有的鸭子都会呱呱叫、会游泳,都有自己的外观,所以我们定义一个父类,把这三个共有的方法定义在父类中,并且把呱呱叫、游泳的方法进行默认的实现,唯独外观方法什么都不做,因为不同的鸭子有不同的外观,所以需要把父类的外观方法定义成抽象方法,并且让具体的子类中强制覆写父类的外观方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* @author maps
* 定义一个鸭子父类
*/
public abstract class Duck {
//呱呱叫方法
public void quack(){
System.out.println("呱呱叫");
}
//游泳方法
public void swim(){
System.out.println("游泳");
}
//外观方法
public abstract void display();
}

1.2、定义一个红色鸭子类-RedDuck,并且继承父类

因为红色鸭子继承了父类,所以其具备了父类定义的所有方法的功能,即默认就会呱呱叫、会游泳;只是这个红色鸭子还没有颜色外观,因为父类的外观方法是抽象方法,所以子类必须覆写该抽象的外观方法

1
2
3
4
5
6
7
8
9
10
11
/**
* @author maps
* 红色鸭子业务类
*/
public class RedDuck extends Duck {
@Override
public void display() {
System.out.println("红头鸭");
}
}

1.3、定义一个绿色鸭子类-GreenDuck,并且继承父类

1
2
3
4
5
6
7
8
9
10
11
/**
* @author maps
* 绿色鸭子业务类
*/
public class GreenDuck extends Duck {
@Override
public void display() {
System.out.println("绿头鸭");
}
}

1.4、定义一个测试类

可以看到生产的红头鸭和绿头鸭默认都实现了父类定义的呱呱叫、游泳动作特征,只是他们都实现自己定义的外观

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Test {
public static void main(String[] args) {
RedDuck redDuck = new RedDuck();//生产一个红头鸭
redDuck.quack();
redDuck.swim();
redDuck.display();
System.out.println("--------------------------");
GreenDuck greenDuck = new GreenDuck();//生产一个绿头鸭
greenDuck.quack();
greenDuck.swim();
greenDuck.display();
}
}

呱呱叫

游泳

红头鸭


呱呱叫

游泳

绿头鸭

2、第二代鸭子

第一代鸭子投入市场后,获得了广泛好评,由于最近无人机的盛行,所以公司决定对第一代鸭子进行创新,开发第二代鸭子–会飞的大黄鸭。

真对这个会飞的大黄鸭新产品,我们立刻就能想到如下解决方案:

在父类中定义一个fly的方法(这个方法不能是抽象方法,因为不能影响第一代鸭子的生产),并且方法不做任何具体实现

2.1、在父类中添加fly方法-Duck

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* @author maps
* 定义一个鸭子抽象类
*/
public abstract class Duck {
//呱呱叫方法
public void quack(){
System.out.println("呱呱叫");
}
//游泳方法
public void swim(){
System.out.println("游泳");
}
//外观方法
public abstract void display();
//飞行的方法
public void fly(){
}
}

2.2、定义大黄鸭业务类-BigYellowDuck

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* @author map
* 定义大黄鸭业务类
*/
public class BigYellowDuck extends Duck {
@Override
public void display() {
System.out.println("大黄鸭");
}
@Override
public void fly() {
super.fly();
System.out.println("天空中飞行");
}
}

2.3、定义一个测试类

可以看到生产的红头鸭和绿头鸭默认都实现了父类定义的呱呱叫、游泳动作特征,只是他们都实现自己定义的外观,尤其是新定义的大黄鸭,除了自己独特的外观外,还有一个独特技能-飞行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Test {
public static void main(String[] args) {
RedDuck redDuck = new RedDuck();//生产一个红头鸭
redDuck.quack();
redDuck.swim();
redDuck.display();
System.out.println("--------------------------");
GreenDuck greenDuck = new GreenDuck();//生产一个绿头鸭
greenDuck.quack();
greenDuck.swim();
greenDuck.display();
System.out.println("--------------------------");
BigYellowDuck yellowDuck = new BigYellowDuck();//生产一个会飞的大黄鸭
yellowDuck.quack();
yellowDuck.swim();
yellowDuck.display();
yellowDuck.fly();
}
}

呱呱叫

游泳

红头鸭


呱呱叫

游泳

绿头鸭


呱呱叫

游泳

大黄鸭

天空中飞行

上面是基本没有应用设计模式的场景,我们思考一下其他问题,比如后期新建很多种具备各自独特功能的鸭子呢?我们是不是要在父类中定义各种对其他鸭子无用的方法,那么以后用设计模式解决吧。