话题之老张去东北
某一年某一天,老张想开汽车去东北赏雪,首先老张需要有一个汽车,于是他花钱买了一辆;
public class Car{
public void run(){
System.out.println("老张开着汽车去东北");
}
}
测试类:
public class test{
public static void main(String[] args) {
Car car = new Car();
car.run();
}
}
运行结果:老张开着汽车去东北
状况:路途太过遥远,老张需要中场休息,但是此时汽车丢了,他需要重新买(new)一个汽车(Car对象)上路;但是他没钱了,怎么办呢?
解决办法:如果老张在最开始的时候不是买汽车,而是从我们全国连锁的大租车厂租了一辆,在他休息的时候交还我们保管汽车,当他再次上路的时候我们再把汽车交还给他,这样不就可以了吗;
我们可以通过添加私有构造方式使得老张没办法买汽车,只能从我们这里租汽车,但是为了老张可以把汽车开走,我们还需要添加一个getIntence()方法;
public class Car{
private Car(){
}
public static Car getIntence(){
return new Car();
}
public void run(){
System.out.println("老张开着汽车去东北");
}
}
但是老张多奸诈,他想从租车厂一下租出好多辆汽车(频繁的调用getIntence()方法)从中挑出一辆最拉风的去东北蹦迪,但是租车厂很尴尬,全国范围只有一辆汽车,为了不让老张识破这一点,我们只能严词拒绝:这叫做单例模式,因为自始至终就只有一个车辆对象
public class Car{
private static Car car = new Car(); // 确保老张每次获取到的都是之前的同一台汽车
private Car(){
}
public static Car getIntence(){
return car;
}
public void run(){
System.out.println("老张开着汽车去东北");
}
}
测试类:
public class test{
public static void main(String[] args) {
Car car = Car.getIntence();
car.run();
}
}
运行结果:老张开着汽车去东北
多例模式:租车厂经过此次事件痛定思痛,下拨了一大笔资金购置了多辆汽车可供选择。终于能满足老张的需求开着拉风的甲壳虫去东北了。
此处不做过多讲解,JDBC连接池本质上就是多例模式的实现
public class Car{
private static List<Car> list = new ArrayList()<Car>;
private Car(){
}
public class List<Car> getIntence(){
return list ;
}
public void run(){
System.out.println("老张开着汽车去东北");
}
}
总结:1.频繁的创建对象会极大的消耗内存,使用工厂模式可以减少内存开销;
2:只要在其实体类中产生了控制对象的逻辑,其本质上就是工厂模式的运用。
普通工厂
为了简化说明,下面代码就不使用单例模式了
老张出发前挖到了清朝的刀币,预算充足,想换个刺激的方式去东北,于是决定开飞机;飞机跟汽车本质上都是可以跑的,此时建立一个抽象类用于提取汽车与飞机的公共特性–跑;
public interface Runner{
public void run();
}
将汽车以及飞机实现此接口,定义各自的run()方法;
public class plane implements Runner{
public void run(){
System.out.println("老张开着飞机去东北");
}
}
public class Car implements Runner{
public void run(){
System.out.println("老张开着汽车去东北");
}
}
建立工厂类(单个工厂)
public class RunnerFactory {
public Runner move(String type) {
if ("plane".equals(type)) {
return new plane();
} else if ("Car".equals(type)) {
return new Car();
} else {
System.out.println("请输入正确的交通工具!");
return null;
}
}
}
测试类:
public class RunnerFactoryTest{
public static void main(String[] args) {
RunnerFactory runnerFactory = new RunnerFactory();
Runner runner= runnerFactory.move("plane");
runner.run();
}
}
运行结果:老张开着飞机去东北
建立工厂类(多个工厂)
public class RunnerFactory {
public Runner planeRunner(){
return new plane();
}
public Runner carRunner(){
return new Car();
}
}
测试类:
public class RunnerFactoryTest{
public static void main(String[] args) {
RunnerFactory runnerFactory = new RunnerFactory();
Runner runner = runnerFactory .planeRunner();
runner.run();
}
}
运行结果:老张开着飞机去东北
存在问题:普通工厂模式代码耦合度较高,每添加一种交通工具,都需要修改工厂类中的代码,而且存在操作人员大量实例化工厂的隐患;单个工厂 模式当传入的参数有误时不能正确的创建对象;
静态工厂
其本质就是将工厂方法加上static关键字,使其不需要创建实例化对象就可以直接调用
public class RunnerFactory {
public static Runner planeRunner(){
return new plane();
}
public static Runner carRunner(){
return new Car();
}
}
测试类:
public class RunnerFactoryTest{
public static void main(String[] args) {
Runner runner = RunnerFactory .planeRunner();
runner.run();
}
}
运行结果:老张开着飞机去东北
静态工厂模式可以解决实例化对象的问题,但是仍然存在代码耦合度过高的缺陷
抽象工厂
老张觉得自己去租车行太麻烦了,于是就找了一个中介,告诉他们自己想租一家飞机;至于中介去找哪家公司就跟老张没关系了;老张中途想换成汽车或者自行车等交通工具的时候只需要通知中介就可以了。
我们将汽车以及飞机的公共特性抽取出来,运用到了多态的思想;为了解决工厂类代码耦合度高的缺点,我们依旧可以使用多态的思想,每一个交通工具建立起各自的工厂类,然后将工厂类的特性再抽取成一个接口。之后再添加交通工具只需要写自己的工厂类实现接口就可以了,完全不会影响到其他工厂类的代码。
public interface Runner{
public void run();
}
public class plane implements Runner{
@Override
public void run(){
System.out.println("老张开着飞机去东北");
}
}
public class Car implements Runner{
@Override
public void run(){
System.out.println("老张开着汽车去东北");
}
}
public interface Vehicle{
public Runner move();
}
public class planeFactory implements Vehicle{
@Override
public Runner move(){
return new plane();
}
}
public class carFactory implements Vehicle{
@Override
public Runner move(){
return new Car();
}
}
测试类:
public class test {
public static void main(String[] args) {
Vehicle vehicle = new planeFactory();
Runner runner = vehicle.move();
runner.run();
}
}
运行结果:老张开着飞机去东北
这样每个交通工具的代码互不关联,老张就可以随意挑选自己心仪的交通工具前往东北赏雪了。