设计模式(简单工厂模式)——Java程序设计基础

一、定义

设计模式:软件模式是将模式的一般概念应用于软件开发领域,即软件开发的总体指导思路或参照样板。软件模式并非仅限于设计模式,还包括架构模式、分析模式和过程模式等,实际上,在软件生存期的每一个阶段都存在着一些被认同的模式。

二、目前主流的设计模式,有三种分类:

(一)按创建型模式分类:

1. 简单工厂模式( Simple Factory Pattern )

2. 工厂方法模式(Factory Method Pattern)

3. 抽象工厂模式(Abstract Factory)

4. 建造者模式

5. 单例模式

(二)按结构型模式分类

1. 适配器模式

2. 桥接模式

3. 装饰模式

4. 外观模式

5. 享元模式

6. 代理模式

 (三)按行为型模式分类

1. 命令模式

2. 中介者模式

3. 观察者模式

4. 状态模式

5. 策略模式

三、简单工厂模式

用一个例子来说明接口、简单工厂模式、控制反转IOC

 1.新建一个项目(项目名称TestSimplyFactoryModel)

2.以汽车为例:汽车可以分为公交车,货车等。我们定义汽车为一个接口,轿车和货车分别实现汽车接口。

创建一个简单工厂包:

输入包名:simpleFactory:

 为了方便,下面的接口和对象请放到这个包里。

3.接下来创建一个汽车接口:

在Car中定义一个show方法:

4.接下来,定义两个类实现汽车接口,一个是公交车类,一个是货车类,同时重写接口的show方法,修改如下:

 

步骤1、如果是传统的方法,不采用工厂模式,我们实例化公交车和货车的方法如下:

我们创建一个主类,在主函数中写上代码,实例化公交车对象和货车对象,并输出它们的show()方法:如下图:

保存并运行程序,查看结果:

步骤2、简单工厂模式

在上面的接口开发中,我们需要记住很多类名:公交车类,货车类,根据它们的类名来实例化它们,比如:

注意上面的代码可以改写为:

Car  c1 = new Bus()

Car  c2 = new Truck();

实际上它们都同属于汽车接口,能否统一一下实例化它们的方法?下面我们就用简单工厂模式改写上面的代码。

(一)我们在包simpleFactory上创建一个类(用来生产汽车,我们叫它工厂类),名类为CaFactory。(不需要继承接口)

在这个CarFactory类中,我们创建一个方法getCar用来生成汽车,它的返回值是接口Car,如下面代码:

package simpleFactory;

public class CarFactory {
    
    public static Car getCar(String type) {
        
        Car carType = null;    //    先定义一个汽车
        
        switch(type)
        {
            case "Bus":
                carType = new Bus();    //    生产公交车
                break;
            
            case "Truck":
                carType = new Truck();    //    生产货车
                break;
        }
        return carType;    //    返回生产出来的汽车类型
    }

}

}

上面我们把实例化汽车的工作都放到了这个CarFactory类里。

(二)回到MainClass类,在Main函数里注释掉前面的代码,修改里面的代码为:

public class MainClass {

  public static void main(String[] args) {

         //工厂模式的方法;

        Car c1 = CarFactory.getCar("Bus");
        Car c2 = CarFactory.getCar("Truck");
        c1.show();
        c2.show();

  }

}

两种方法的对比:

注意到使用简单工厂模式之后,实例化的时候都采用同样的方式去实例,只是在参数中指明是哪个类。

步骤三、使用反射

回到我们的CarFactory类,里面使用switch语句区分每一种水果类,如果水果类有很多种,这样的写法非常麻烦。

public class CarFactory {

   public static Car getCar(String type) {

          /*这里通过反射的方式获取到汽车子类的字节码,即类对象,通过类对象的newInstance()方法创建汽车子类*/

          Class car = Class.forName(CarFactory.class.getPackage().getName()+"."+type);

       return (Car) carType.newInstance();

      }

}

(这里CarFactory.class.getPackage().getName()是用来找到CarFactory所在的包,你也可以直接写上你汽车类所在的包的名称,如”simFactory.”+type

然后鼠标移到所有有波浪线的代码上,点add.throw.declaration

如下图:

再回到主类MainClass的主函数Main中,鼠标移到波浪线上右击,添加add.throw.declaration

(注意:这里将工厂类和所创建的子类放在同一个包CarFactory中,方便调用。)

上面通过反射的方式获取到汽车子类的字节码,即类对象,通过类对象的newInstance()方法创建汽车子类。

保存运行后,结果虽然不变,但是这里采用了反射的方法,不需要去判断有多少种汽车,分别写上代码,但是这里要加上throw的预出错处理,防止用户写错类名,无法创建出对应的类。

上面的简单工厂模型实现了控制反转(Ioc)的概念,即创建类的对象由Bus,Truck转移到CarFactory这个工厂类上。

完整代码:

public interface Car {
	public void show();

}


public class Bus implements Car{

	public void show() {
		
		System.out.println("这是公交车!");
	}

}


public class Truck implements Car {

	public void show() {
		
		System.out.println("这是货车!");
	}

}


public class CarFactory {
	
		@SuppressWarnings("deprecation")
	public static Car getCar(String type) throws ClassNotFoundException, InstantiationException, IllegalAccessException { // 方法是静态的,可以不用创建对象直接用类名访问
		
//      使用反射
		@SuppressWarnings("rawtypes")
		Class carType = Class.forName(CarFactory.class.getPackage().getName()+"."+type);
		return (Car)carType.newInstance();
		
/*		
        简单工厂模式的方法
		switch(type)
		{
			case "Bus":
				carType = new Bus();	//	生产公交车
				break;
			
			case "Truck":
				carType = new Truck();	//	生产货车
				break;
		}
		
		return carType;	//	返回生产出来的汽车类型
	
*/
		
	}
}


public class MainClass {

	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
			
/* 
	传统方法:
		Bus b = new Bus();		// 实例化公交车对象
		Truck t = new Truck();	// 实例化货车对象
		b.show();
		t.show();	
*/		
		
/*	
 	简单工厂模式的方法
	   Car c1 = CarFactory.getCar("Bus");
	   Car c2 = CarFactory.getCar("Truck");
	   c1.show();
	   c2.show();
*/		
		
// 使用反射
	   Car c1 = CarFactory.getCar("Bus");
	   Car c2 = CarFactory.getCar("Truck");
	   c1.show();
	   c2.show();
	   
	}

}


实例:

请创建一个项目Test,练习简单工厂模式

要求:请定义一个水果的接口Fruit,里面有显示水果的方法showFruit()。定义几个水果类:苹果(Apple,香蕉(Banana) 它们的showFruit方法为显示自己的水果名称,并定义一个生产水果的工厂类 FruitFactory,

请用工厂模式实例化一个苹果对象,和一个香蕉对象,并输出它们的showFruit()方法。

代码示例:

public interface Fruit {
	public void showFruilt();
}

public class Apple implements Fruit {

	public void showFruilt() {
		System.out.println("苹果");

	}

}

public class Banana implements Fruit {

	public void showFruilt() {
		System.out.println("香蕉");

	}

}

public class FruitFactory {
	
	public static Fruit getFruit(String type) {
		
		Fruit fruitType = null;
		
		switch(type) {
			case "Apple":
				fruitType = new Apple();
				break;
				
			case "Banana":
				fruitType = new Banana();
				break;
		}
		
		return fruitType;
	}
}

public class MainCLass {

	public static void main(String[] args) {
		
		Fruit f1 = FruitFactory.getFruit("Apple");
		Fruit f2 = FruitFactory.getFruit("Banana");
		f1.showFruilt();
		f2.showFruilt();

	}

}

猜你喜欢

转载自blog.csdn.net/Mr_Morgans/article/details/121420389