Java设计模式之一

这几天公司没有什么事做,就看了看java的设计模式,收益匪浅!通读了一下23种设计模式,着重看了一下经常用到的几种设计模式:单例模式,工厂模式,迭代模式,代理模式,策略模式等,也敲了敲相关的代码,我觉得设计模式是一些设计思想,一些简单的问题复杂化,但是复杂的又好有道理,主要解决程序的(extensibility)可扩展性。java源码和经常用到的的一些框架如struts2和spring都使用或者封装了这些设计模式,所以我觉得设计模式太重要了,学好了它对读源码深入理解框架背后的原理,以及以后coding或者重构都会有很大帮助,所以打算花一段时间系统的学习一下,先把这本书读一遍《Head First设计模式》。

1、单例模式(Singleton Pattern)

     单例模式能够保证在JVM中只有一个实例存在。可以省去new,减少内存使用频率,还有一些核心的类在内存中只能有一个实例。

如下

package com.remote3c.singleton;

public class Car {
	
	//构造方法设置为private,只能它自身创建对象,其他地方不能 new Car()
	private Car(){
	}
	
	//生产一个静态的car对象,保证JVM中只有一个
	private static Car car = new Car();
	
	//添加获取实例的方法
	public static Car getInstance(){
		return car;
	}
}

测试
package com.remote3c.singleton;

public class Test {

	/**
	 * @author zhangyoushuai
	 * @version 1.0.0 
	 * @param args
	 */
	public static void main(String[] args) {
		
		Car car1 = Car.getInstance();
		Car car2 = Car.getInstance();
		if(car1==car2){
			System.out.println("car1=car2");
		}
	}

}

还有一种更好的写法,需要的时候再产生。

public class Singleton {  
      
    private Singleton(){}  
      
    public static Singleton getInstance(){  
        return SingletonInstance.instance;  
    }  
      
    private static class SingletonInstance{  
          
        static Singleton instance = new Singleton();  
          
    }  
} 



2、工厂模式(FactoryPattern)

当需要大量的创建对象时,可以考虑工厂模式,工厂模式特点创建对象和使用对象分开。

简单工厂,模拟 老张开车去东北,老张可以开着车,可以开着飞机,也可以骑着扫帚等等交通工具, 实现任意变换交通工具和生产交通工具的过程。

一提到任意变换,肯定用到多态,用到多态肯定就少不了继承,重写,父类引用指向子类对象。这里的继承泛指实现。

首先我们写一个交通工具的接口Moveable:

package com.remote3c.simplefactory;

public interface Moveable {
	public void run();
}
接着写实现了这个接口的具体的交通工具car和palane

package com.remote3c.simplefactory;

public class Car implements Moveable {

	public void run() {
		System.out.println("开着车,冒着烟,突突突突……去了东北");
	}

}

package com.remote3c.simplefactory;

public class Plane implements Moveable {

    public void run() {
        System.out.println("开着飞机,呜呜呜呜……的去了东北");

    }

}

按照题意还要实现任意变换生产交通工具的生产过程,那就先建立一个交通工具的接口

package com.remote3c.simplefactory;

public interface VehicleFactory {
    //生产交通工具  Vehicle-交通工具
    public Moveable produce();
}

接着写实现了这个接口的car工厂和plane工厂

package com.remote3c.simplefactory;
/**
 * @author zhangyoushuai
 * 汽车工厂
 */
public class CarFactory implements VehicleFactory{

	public Moveable produce() {
		
		return new Car();
	}

}

package com.remote3c.simplefactory;
/**
 * @author zhangyoushuai
 * 飞机工厂
 */
public class PlaneFactory implements VehicleFactory {

	public Moveable produce() {
		return new Plane();
	}

}
最后写测试类

package com.remote3c.simplefactory;

public class Test {

	/**
	 * @author zhangyoushuai
	 * @version 1.0.0 
	 * @param args
	 * 模拟 老张开车去东北
	 * 老张可以开着车,也可以开着飞机,骑着扫帚等等交通工具
	 * 实现任意变换交通工具和生产交通工具的过程
	 * 当需要大量的创建对象时,可以考虑工厂模式,工厂模式特点创建对象和使用对象分开
	 */
	public static void main(String[] args) {
		/**
		     这里可以任意变换生产交通工具的工厂,下面去东北所乘的交通工具也随之改变
		     当有新的交通工具添加进来的时候,只需实现moveable接口创建交通工具,
                          再实现VehicleFactory接口创建工厂即可,
         */
		VehicleFactory vehicle =new PlaneFactory();
//		VehicleFactory vehicle =new CarFactory();
		Moveable moveable =vehicle.produce();
		moveable.run();
	}

}


3、抽象工厂模式(AbstractFactoryPattern)

 上面的工厂模式,有时候会造成很多工厂,工厂泛滥的情况,还有就是乘交通工具的同时再有吃着东西,打着枪等行为时该怎么办呢?

抽象工厂就是同时解决一系列产品或行为的一种模式,提供一个接口,用于创建相关或者依赖对象的家族。而不像上面那样一个工厂只生产一种产品或者行为,

而是生产一系列的产品或者行为。

下面用代码详细的模拟乘着交通工具,吃着食物,拿着武器一系列行为去东北的情况

首先创建一个抽象的总工厂

package com.remote3c.abstractfactory;

public abstract class AbstractFactory {
	public abstract Vehicle createVehicle();//生产交通工具
	public abstract Weapon createWeapon();//生产武器
	public abstract Food createFood();//生产食物
}

接着再创建 Vehicle(交通工具),Weapon(武器),Food(食物)的抽象类

package com.remote3c.abstractfactory;

public abstract class Vehicle {
	public abstract void run();
}
package com.remote3c.abstractfactory;

public abstract class Weapon {
	public abstract void shoot();
}
package com.remote3c.abstractfactory;

public abstract class Food {
	public abstract void getName();
}
同时Vehicle有run(),Weapon有shoot(),Food有getName()方法,

接着通过实现Vehicle,Weapon,Food创建真正的交通工具,武器,食物

交通工具

package com.remote3c.abstractfactory;

public class Car extends Vehicle {

	@Override
	public void run() {
		System.out.println("开着车 突突突突………………");

	}

}
package com.remote3c.abstractfactory;

public class Broom extends Vehicle {
	//扫帚
	@Override
	public void run() {
		System.out.println("骑着扫帚呼啦哗啦,狼烟滚滚而去…………");

	}

}

具体的武器
package com.remote3c.abstractfactory;

public class AK47 extends Weapon {

	@Override
	public void shoot() {
		System.out.println("拿着武器AK47,发射 突突突突突……");

	}

}
package com.remote3c.abstractfactory;

public class Magicstick extends Weapon {
	//魔法棒
	@Override
	public void shoot() {
		System.out.println("挥舞着魔法棒 天灵灵,地灵灵,魔法棒快显灵……");

	}

}

具体的食物
package com.remote3c.abstractfactory;

public class Apple extends Food {

	@Override
	public void getName() {
		System.out.println("吃着 Apple");
	}

}
package com.remote3c.abstractfactory;

public class Mushroom extends Food {
	//蘑菇
	@Override
	public void getName() {
		System.out.println(" 吃着  Mushroom");
	}

}

好了接下来该建立真正的工厂了

正常的普通的工厂

package com.remote3c.abstractfactory;

public class NormalFactory extends AbstractFactory {
	//正常的,一般的工厂
	@Override
	public Food createFood() {
		// TODO Auto-generated method stub
		return new Apple();
	}

	@Override
	public Vehicle createVehicle() {
		// TODO Auto-generated method stub
		return new Car();
	}

	@Override
	public Weapon createWeapon() {
		// TODO Auto-generated method stub
		return new AK47();
	}

}
带有魔法的工厂
package com.remote3c.abstractfactory;

public class MagicFactory extends AbstractFactory{
	//有魔法的工厂
	@Override
	public Food createFood() {
		// TODO Auto-generated method stub
		return new Mushroom();
	}

	@Override
	public Vehicle createVehicle() {
		// TODO Auto-generated method stub
		return new Broom();
	}

	@Override
	public Weapon createWeapon() {
		// TODO Auto-generated method stub
		return new Magicstick();
	}

}

最后终于写完了,该写测试程序啦

package com.remote3c.abstractfactory;

public class Test {

	/**
	 * @author zhangyoushuai
	 * @version 1.0.0 
	 * @param args
	 */
	public static void main(String[] args) {
		//在这里可以随意的切换工厂,添加工厂也不用修改现有的code,具有很强的extensibility可扩展性
//		AbstractFactory ab = new NormalFactory();
		AbstractFactory ab = new MagicFactory();
		
		Vehicle vehicle = ab.createVehicle();
		vehicle.run();
		Food food = ab.createFood();
		food.getName();
		Weapon weapon = ab.createWeapon();
		weapon.shoot();
	}

}
测试结果

骑着扫帚呼啦哗啦,狼烟滚滚而去…………
 吃着  Mushroom
挥舞着魔法棒 天灵灵,地灵灵,魔法棒快显灵……

这就是抽象工厂,可以同时切换一族行为或产品,当你需要创建产品家族或想让制造的相关产品集合起来时,可以考虑使用抽象工厂。

但是抽象工厂也有它的短处,就是新增一种行为时,比如乘着交通工具,吃着东西,拿着武器的同时,再增加一种听着音乐的行为时,就需要改变抽象总工厂,会很麻烦。

如果行为不确定,最好不要用这种方法。

网上一些模式相关的链接
http://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.html

http://www.uml.org.cn/j2ee/201010214.asp

https://www.zhihu.com/question/39972591


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值