这是我第四次对设计模式进行大规模的扫荡。第一次是在大三上的时候,自己找设计模式之禅进行扫荡,第二次是在网上看别人的博客进行了一次扫荡,第三次是在面试之前对已经掌握的还有常考的进行扫荡,第四次是在上设计模式的课程的时候进行的扫荡。
看网上博客的地址:http://blog.csdn.net/zhangerqing/article/details/8194653
这个博客又优点也有缺点。
优点:覆盖面广,这个博客对于所有的设计模式涉及到的知识都有涉及,从六个原则开始到各个模式的类图,点评都写得很好,是学习设计模式一个很好的博客。
缺点:部分模式太过于简洁,是最简单化的设计模式,有些需要进行子类扩展的地方没有进行扩展。例如装饰模式,在这个模式里面对装饰者没有进行扩展,装饰者可以进行不同装饰的特性没有进行提现。
本文适合对设计模式有一定了解的人看的,初学者可以去先看看上面那篇博客。
One:
工厂模式:由于该模式跟现实生活中的工厂很想,所以起名工厂模式。工厂,大家的第一印象是生产某种东西,工厂模式也是确实如此。工厂类是负责生产其他的某种东西的,一般的话是生产某种类对象。在工厂类中可以在一个函数中生产多种对象,也可以多个函数生产,一个函数中生产一个这两种方式。
public Sender produceMail(){
return new MailSender();
}
public Sender produceSms(){
return new SmsSender();
}
public Sender produce(String type) {
if ("mail".equals(type)) {
return new MailSender();
} else if ("sms".equals(type)) {
return new SmsSender();
} else {
System.out.println("请输入正确的类型!");
return null;
}
}
另外还有种静态工厂模式:
public class SendFactory {
public static Sender produceMail(){
return new MailSender();
}
public static Sender produceSms(){
return new SmsSender();
}
}
这种方式是不用生产工厂对象,可以直接进行调用,大家感受一下。
Sender sender = SendFactory.produceMail();
sender.Send();
这是因为静态函数是隶属于类的,可以由类直接进行调用,所以会方便一些。
Two:抽象工厂方法
工厂模式是没有任何技术含量的但是又简单易懂所以就摆在第一个进行讲解。没有类之间的继承和实现接口啊这些,也就是没有抽象和具体。
抽象工厂方法对于工厂方法来说的话只是多了一个抽象的概念。
这里面在Provider抽象类或者是接口中定义一个produce()函数,然后由不同的子类对其进行不同的实现,这里也即是生产不同的产品。
打个比方;Provider抽象级别的公司,也就是概念中的公司。下面两个是具体的比如说卖鱼的和卖鸡的,你要宰好的鱼就去生产鱼的公司,你要买鸡就去生产鸡的公司。
优点:这个对于工厂模式来说引入了抽象,可以进行很好的扩展。比如现在有一个卖鹅的公司加进来的话,我们就可以再不用更改其他类的前提下进行扩展。
Three:单例模式
这个模式来说基本的就是三点:私有静态实例,私有的构造函数,公有的静态工程方法,创建实例。
public class Singleton {
/* 持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载 */
private static Singleton instance = null;
/* 私有构造方法,防止被实例化 */
private Singleton() {
}
/* 静态工程方法,创建实例 */
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
这个显然不能适用于多线程,想去了解多线程下的朋友可以去看剑指offer,里面有详细的讲解。
Four:建造者模式
建造者模式中对于分工是分的很细的,比如说造车。
Car类中是Car的基本属性。
package com.zcl.design.builder;
public class Car {
private String wheel;
private String engine;
private String carFrame;
public String getWheel() {
return wheel;
}
public void setWheel(String wheel) {
this.wheel = wheel;
}
public String getEngine() {
return engine;
}
public void setEngine(String engine) {
this.engine = engine;
}
public String getCarFrame() {
return carFrame;
}
public void setCarFrame(String carFrame) {
this.carFrame = carFrame;
}
public void getInformation() {
System.out.println("轮子:" + wheel + " 引擎:" + engine + " 汽车架构:" + carFrame);
}
}
对于实际的生产者来说我们引入抽象,接口Ibuilder
package com.zcl.design.builder;
public interface Ibuilder {
public void buildWheel();//建造汽车轮子
public void buildEngine();//建造汽车引擎
public void buildCarFrame();//建造汽车框架
}
实现接口:
package com.zcl.design.builder;
/**
* @author ZCL 实际的生产者
*/
public class CarBuilder implements Ibuilder {
private Car car=null;
public CarBuilder() {
this.car = new Car();
}
@Override
public void buildWheel() {
car.setWheel("海尔");
}
@Override
public void buildEngine() {
car.setEngine("松下");
}
@Override
public void buildCarFrame() {
car.setCarFrame("三星");
}
public Car CarBuildOver() {
System.out.println("汽车组装完毕");
return car;
}
}
然后Builder强对于其他设计模式来说多的是一个导演类,该类的作用是可以决定采用何种顺序或者方式来组装的车子。
package com.zcl.design.builder;
/**
* @author ZCL
* 导演类起到封装的作用,避免高层模块深入到建造者内部实现类
* 决定汽车的建造顺序
*/
public class CarDirector {
public Car BuildCar(CarBuilder carBuilder) {
carBuilder.buildCarFrame();
carBuilder.buildEngine();
carBuilder.buildWheel();
return carBuilder.CarBuildOver();
}
}
在上面的类中,我们可以看到早BuildCar函数中我们决定了car的组装的顺序,我们也可以在建立一个类然后更换它的组装顺序,然后达到客户的相关要求。
下面是Client即测试类。
package com.zcl.design.builder;
public class Client {
public static void main(String[] args) {
CarDirector carDirector = new CarDirector();
Car car = carDirector.BuildCar(new CarBuilder());
car.getInformation();
}
}