今天闲来无事,着手看了一下工厂模式的内容,在这里做一个记录
先写了一下实体产品类,这个是在几个不同的工厂模式都有用到的类。
Product基类
package com;
public class Product {
public void speak() {
}
}
BikeProduct
package com.product;
import com.Product;
public class BikeProduct extends Product {
@Override
public void speak() {
// TODO Auto-generated method stub
System.out.println("i am the bike");
}
}
CarProduct
package com.product;
import com.Product;
public class CarProduct extends Product {
@Override
public void speak() {
// TODO Auto-generated method stub
System.out.println("i am the car");
}
}
接下来我们来一个一个分析各个不同的工厂模式:
一、普通工厂模式SimpleFactory
package com.factory;
import com.Product;
import com.product.BikeProduct;
import com.product.CarProduct;
public class SimpleFactory {
public Product createProduct(String productName) throws Exception {
if ("car".equals(productName)) {
return new CarProduct();
} else if ("bike".equals(productName)) {
return new BikeProduct();
} else {
throw new Exception("please input the correct name");
}
}
}
我们可以看到是在该类的方法中传入一个productName值,通过传入的productName来判断返回的具体的Product,如果传入一个非法值,就抛出一个异常,并传递回去Log信息做提醒。
二,多个工厂模式MultiFactory
package com.factory;
import com.Product;
import com.product.BikeProduct;
import com.product.CarProduct;
public class MultiFactory {
public Product createBikeProduct() {
return new BikeProduct();
}
public Product createCarProduct() {
return new CarProduct();
}
}
在这里我们强制定义了工厂类中的返回内容(产品类型),只能返回我们之前定义好的产品类型,这样当我们再使用时,就不用担心会出现去创建一个不存在的产品了。
三,静态工厂模式StaticFactory
package com.factory;
import com.Product;
import com.product.BikeProduct;
import com.product.CarProduct;
public class StaticFactory {
public static Product createCarProduct() {
return new CarProduct();
}
public static Product createBikePoduct() {
return new BikeProduct();
}
}
静态工厂模式,与多个工厂模式相比,将产品的产生方法定义成了static静态方法,这样在使用时,就不再需要创建一个Factory的实体类,直接调用Manager的create方法就可以直接创建我们需要的产品类了。在使用时,大多数情况下大家都倾向于使用静态工厂模式去替代多个工厂模式。如果新增了一个产品(AirPlaneProduct),只需要在工厂里面新增一条产线(createAirPlaneProduct)就行了,这个产线专门生产该产品(AirPlaneProduct)。
四、工厂方法模式AbstractFactory
在这里提一下工厂方法模式的优势:在之前的几种模式中,如果我们对产品进行了扩展,比如我又新增了一个AirPlane产品,那么我不仅需要新增一个这样的产品类型,我还得需要修改Factory的内容,以便在使用时才能使用到这个Airplane产品,但是这显然违背了Java扩展性的内容,在这种情况下,工厂方法模式就诞生了。
我们可以抽象出来一个Factory,再创建出来几个不同的实体类Factory,并实现这个抽象类,这样如果我们新增的产品,只需要新生成一个新的针对产品(AirplaneProduct)实体Factory就可以了。不需要修改原有的代码结构和内容。
如下:
抽象AbstractFactoty
package com.factory;
import com.Product;
public interface AbstractFactory {
public Product produce();
}
package com.entityfactory;
import com.Product;
import com.factory.AbstractFactory;
import com.product.BikeProduct;
public class BikeFactory implements AbstractFactory{
@Override
public Product produce() {
// TODO Auto-generated method stub
return new BikeProduct();
}
}
package com.entityfactory;
import com.Product;
import com.factory.AbstractFactory;
import com.product.CarProduct;
public class CarFactory implements AbstractFactory{
@Override
public Product produce() {
// TODO Auto-generated method stub
return new CarProduct();
}
}
这样在新增工厂的时候直接新增Factory就可以扩展了。从这里可以看出,工厂方法模式试针对产品为中心的,如果新增了一个产品(AirPlaneProduct),那么就需要新增一个针对该产品的工厂(AirplaneFactory),这个工厂仅仅生产新增的产品(AirPlaneProduct)。
接下来我们来写一个测试类,测试一下我们这几种工厂模式的使用
package com.test;
import com.Product;
import com.entityfactory.CarFactory;
import com.factory.AbstractFactory;
import com.factory.MultiFactory;
import com.factory.SimpleFactory;
import com.factory.StaticFactory;
public class Main {
public static void main(String[] args) {
// --------------简单工厂模式
SimpleFactory simpleFactory = new SimpleFactory();
try {
Product product = simpleFactory.createProduct("car");
product.speak();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// --------------多个工厂模式
MultiFactory multiFactory = new MultiFactory();
Product product = multiFactory.createBikeProduct();
product.speak();
// --------------静态工厂模式
Product prudoct1 = StaticFactory.createCarProduct();
product1.speak();
// --------------抽象工厂模式
AbstractFactory abstractFactory = new CarFactory();
Product product2 = abstractFactory.produce();
product2.speak();
}
}
测试结果如下:
i am the car
i am the bike
i am the car
i am the car
从上面四种工厂模式可以看出,从上至下是一步步逐渐针对上一个模式进行的优化,当然了,在具体使用时,并不是说一定要采用最后一种模式去使用,而是要根据实际情况,具体环境去选择。
后面还有一个抽象工厂,等我看完了再写一篇~
由于我的水平有限,在工作中还不能很好的将设计模式带入,使得自己的代码很有结构,很优美,但是我希望我以后可以将这些化为自己的东西,在我的知识转化成代码内容。让自己的水平有提升。