有过软件开发经验的同学都知道,软件开发功能怎么都能完成。但是如果需要在软件上面不断做需求变更和重构,这就变得好复杂了。对于这些变更,如果只是硬编码去解决,那么代码就会写的越来越脏,直到不能维护。如果用一定的套路去重构接口,这样才能在快速响应客户需求的同时,还能保证软件的质量要求。
上面说到的套路,就是设计模式。说到设计模式,很多人都会想到《设计模式》这本书,对于开发经验不是很足的同学,确实有点晦涩难懂。所以,还是建议大家有了一定开发经验再看这本书。
设计模式一般分成是三类,一类是对象如何创建;一类是如果用类和对象创建更大的对象;一类是不同对象之间如何交互。今天主要讨论对象如何创建。
1、基础类图
说明设计模式比较好的方法就是画类图,上图就是一个简单的类图。第一行是类名;第二行是变量;第三行是函数名。如果前面是-,代表是private变量。如果是+,代表是public。
2、设计模式和编程语言
设计模式只是代表一种经验总结,和具体的编程语言没有关系。很多人认为,只能用高级语言才能实现设计模式。其实不然,比如c,也可以实现设计模式。在linux kernel中,其实就有很多的地方用了设计模式,只是大家比较少注意而已。
3、第一个模式,单例模式
单例模式是笔试、面试中经常用到的一个模式。这种模式其实和现实场景是分不开的,比如一个学校只能有一个校长,一个医院只能有一个院长,一个城市只能有一个市长,这都是一个道理。学生应聘的时候,考23个模式太多,所以常用来考试的就是单例模式了。
如果写成代码的话,应该是这样的,
import java.io.*;
public class singleton
{
public static singleton s;
private singleton()
{
return;
}
public static singleton get_instance()
{
if(null == s)
{
s = new singleton();
}
return s;
}
public void show()
{
System.out.println("singleton show function defined here!");
}
public static void main(String args[])
{
s = singleton.get_instance();
s.show();
}
}
4、原型模式
原型模式,顾名思义,就是希望克隆一个一模一样的对象,有点类似于c++里面的拷贝构造函数。如果画成图,可以这么来表示,
写成代码的话,应该是这样的,
import java.io.*;
public class object
{
public object()
{
return;
}
public object(object o)
{
return;
}
public object clone(object o)
{
return new object(o);
}
public void show()
{
System.out.println("show function defined here!");
}
public static void main(String args[])
{
object o = new object();
object copy = o.clone(o);
copy.show();
}
}
5、简单工厂
简单工厂是实际应用中出现频率比较高的模式。假设自己编写一个音乐播放器,那么势必要支持各种各样的文件格式。为了提炼出主流程,我们其实可以提炼出公共接口,比如打开文件、关闭文件、解码文件、时间跳跃等等。如果是工厂生产的话,我们可以这么提炼,
转成java后,代码是这样的,
import java.io.*;
class product
{
public void produce()
{
return;
}
}
class productA extends product
{
@Override
public void produce()
{
System.out.println("produce productA");
}
}
class productB extends product
{
@Override
public void produce()
{
System.out.println("produce productB");
}
}
public class factory
{
public product gen_product(String s)
{
if(s == "A")
return new productA();
else if(s == "B")
return new productB();
else
return null;
}
public static void main(String args[])
{
factory f = new factory();
product p1 = f.gen_product("A");
p1.produce();
product p2 = f.gen_product("B");
p2.produce();
}
}
6、工厂方法
工厂方法相比较简单工厂而言,要更复杂一点。简单工厂可能只生产一种商品,而工厂方法是有多个工厂,生产多个商品。假设有商品A1、A2、B1、B2,那么工厂1生产A1和B1,工厂2生产A2和B2。可以通过一个图来表示,
简单转换一下图形,对应的java代码是这样的,
import java.io.*;
class productA
{
public void produce()
{
return;
}
}
class productA1 extends productA
{
@Override
public void produce()
{
System.out.println("produce productA1");
}
}
class productA2 extends productA
{
@Override
public void produce()
{
System.out.println("produce productA2");
}
}
class productB
{
public void produce()
{
return;
}
}
class productB1 extends productB
{
@Override
public void produce()
{
System.out.println("produce productB1");
}
}
class productB2 extends productB
{
@Override
public void produce()
{
System.out.println("produce productB2");
}
}
abstract class factory
{
public abstract productA gen_productA();
public abstract productB gen_productB();
}
class factory1 extends factory
{
@Override
public productA gen_productA()
{
productA p = new productA1();
p.produce();
return p;
}
@Override
public productB gen_productB()
{
productB p = new productB1();
p.produce();
return p;
}
}
class factory2 extends factory
{
@Override
public productA gen_productA()
{
productA p = new productA2();
p.produce();
return p;
}
@Override
public productB gen_productB()
{
productB p = new productB2();
p.produce();
return p;
}
}
public class bigfactory
{
public static void main(String args[])
{
factory f1 = new factory1();
f1.gen_productA();
f1.gen_productB();
factory f2 = new factory2();
f2.gen_productA();
f2.gen_productB();
}
}
7、建造者模式
建造者模式之前我也不是很明白,直到后来我想到了一汽的案例,就一下子明白了。熟悉汽车的朋友都知道,奥迪和迈腾都属于大众公司。但是大家不太熟悉的时候,很多时候这两款车是共线生产的。比如一样的发动机,一样的变速箱,一样的底盘,一样的轮胎等等。所以,不管品牌如何,他们其实是同一个工厂生产的,只是最后产品的贴牌不一样。
回到设计模式,其实就好比具体生产的对象是一样的,但是生产的品牌是不一样的。如果画成图,可以这么来画,
同样需要用java代码实现一下,
import java.io.*;
class factory
{
void build_partA(String str)
{
System.out.println("build partA for " + str);
}
void build_partB(String str)
{
System.out.println("build partB for " + str);
}
void build_partC(String str)
{
System.out.println("build partC for " + str);
}
}
class vehicle
{
protected factory f;
public vehicle()
{
f = new factory();
}
public void build_partA()
{
return;
}
public void build_partB()
{
return;
}
public void build_partC()
{
return;
}
}
class vehicle1 extends vehicle
{
public void build_partA()
{
f.build_partA("audi");
}
public void build_partB()
{
f.build_partB("audi");
}
public void build_partC()
{
f.build_partC("audi");
}
}
class vehicle2 extends vehicle
{
public void build_partA()
{
f.build_partA("volkswagen");
}
public void build_partB()
{
f.build_partB("volkswagen");
}
public void build_partC()
{
f.build_partC("volkswagen");
}
}
public class build
{
public static void main(String args[])
{
vehicle v1 = new vehicle1();
v1.build_partA();
v1.build_partB();
v1.build_partC();
vehicle v2 = new vehicle2();
v2.build_partA();
v2.build_partB();
v2.build_partC();
}
}
8、其他
关于设计模式这块,我的经验就是反复想、反复试,写错了、理解错了都不是事。哪怕一个模式学了几遍、十几遍都不能理解,也没关系,只要继续尝试,总有理解的时候。此外即使暂时理解不了,后面软件开发多了,也自然而然就会理解的。