1、how is FactoryParrten?
工厂模式就是专门负责将大量有共同接口的类实例化,而且不必事先知道每次是要实例化哪一个类的模式。它定义一个用于创建对象的接口,由子类决定实例化哪一个类。
啥也不说,先上一个UML,分析一波简单工厂模式。
上代码:
//我们先把产品这个类给抽象起来
public abstract class Product {
//产品名称
public String name;
//构造一个产品
public Product(String name) {
super();
this.name = name;
}
public abstract void say();
}
//平板
public class Ipad extends Product{
public Ipad(String name) {
super(name);
}
public void say(){
System.out.println("我是"+name);
}
}
//笔记本
public class NoteBook extends Product{
public NoteBook(String name) {
super(name);
// TODO Auto-generated constructor stub
}
public void say(){
System.out.println("我是"+name);
}
}
接下来是工厂类:
public class ProductFactory {
//工厂方法
public static Product getInstance(String name){
if (name.equals("手机")) {
return new Phone("手机");
}else if(name.equals("平板")){
return new Ipad("平板");
}else if(name.equals("笔记本")){
return new NoteBook("笔记本");
}else{
return null;
}
}
public static void main(String[] args) {
Product p1 = ProductFactory.getInstance("平板");
p1.say();
Product p2 = ProductFactory.getInstance("笔记本");
p2.say();
}
}
简单工厂没什么好说的,看看代码就知道他怎么实现了。
但是,他有一个缺陷,假设需要加产品的时候,比如,当我们要往里面加一个耳机,此时,我们也需要在工厂里面在把耳机给加进去,这样就违背了设计模式的原则,对扩展开放,堆修改关闭,所以这种简单工厂模式,扩展性不好。
接下来,我们可以结合反射,看看能否解决这个问题。
此时我们将工厂类做一番修改:
public class ProductFactory {
public static Product getInstance(Class<?> c,String name){
try {
@SuppressWarnings("unchecked")
//获得Product的构造器
Constructor<Product> c1 = (Constructor<Product>) c.getConstructor(String.class);
//通过构造器创建对象
Product p = c1.newInstance(name);
return p;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
//而在这里我们只需要将这个类的字节码文件和构造器所需的参数传进来即可
Product p1 = ProductFactory.getInstance(Ipad.class,"笔记本");
p1.say();
//下面是我增加的一个产品,不需要修改工厂类,动态的创建对象,你传什么,我给你创建什么
Product p2 = ProductFactory.getInstance(Redio.class,"收音机");
p2.say();
}
}
这是新增的一个产品,这个时候无论我们新增多少产品都可以不需要修改我们的工厂类,只需要继承Product类即可,这就是对扩展开放,对修改关闭。
public class Redio extends Product{
public Redio(String name) {
super(name);
// TODO Auto-generated constructor stub
}
@Override
public void say() {
System.out.println("我是"+name);
}
}
还有一种方式,也是对扩展开放,对修改关闭。那就是采用工厂方法模式。
老规矩,先上uml;
此种方式的原理就是,把工厂细分成多个工厂,假设我需要创建一辆宝马车,在搞一个创建宝马的工厂,然后,通过工厂方法创建我们所需要的对象,只要这个宝马工厂实现CarFactory即可。这种方式也可以对外扩展开放,对内修改关闭,我不许要修改任何的我的内部代码,实现了扩展,当然,这种方式非常的笨重,后期假设我们的类越来越多,工厂也随之越来越多,整个代码就不易于维护。
下面是他的代码:
Car接口:
public interface Car {
void run();
}
下面是他的一些子类:
public class Audi implements Car {
@Override
public void run() {
System.out.println("奥迪再跑!");
}
}
public class Benz implements Car {
@Override
public void run() {
System.out.println("奔驰再跑!");
}
}
public class Byd implements Car {
@Override
public void run() {
System.out.println("比亚迪再跑!");
}
}
下面是CarFactory
public interface CarFactory {
Car createCar();
}
下面是他的子类工厂:
public class AudiFactory implements CarFactory {
@Override
public Car createCar() {
return new Audi();
}
}
public class BenzFactory implements CarFactory {
@Override
public Car createCar() {
return new Benz();
}
}
public class BydFactory implements CarFactory {
@Override
public Car createCar() {
return new Byd();
}
}
测试类:
public class Client {
public static void main(String[] args) {
Car c1 = new AudiFactory().createCar();
Car c2 = new BydFactory().createCar();
c1.run();
c2.run();
}
}
还有一种模式,抽象工厂模式
先给一波此种模式定义:
抽象工厂模式(Abstract Factory Pattern):是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
下面是描述他的UML:
图解:
看图假设我们有一体个汽车工厂,这个工厂可以生产座椅、轮胎、引擎等,当然这个汽车工厂我们把它抽象起来,定义成接口,他本身不创建车,让他的子类来完成,而此时,他可以有很多子类,比如高端汽车工厂,和低端汽车工厂。
然而我们的各种组件也有优劣之分,也就是说,我们有高端座椅,低端座椅,高端引擎,低端引擎,高端轮胎和低端轮胎。假设我们这是要创建高端汽车,就需要高端引擎+高端座椅和高端轮胎。我们要创建低端汽车就需要低端座椅+低端引擎,低端轮胎。假设需要中级汽车,然后根据你自己的需求自己构造。
再谈扩展性:
假设此时我们需要增加一个组件,比如我们需要增加一个方向盘,此时就需要在定义一个创建方向盘这个组件的方法,也就是在我们的CarFactory里面加一个createFXP()的抽象方法,然后在定义一个方向盘接口,实现他的子类有高端方向盘或者低端方向盘。然后我们的汽车(高端汽车工厂或低端汽车工厂)工厂在创建汽车的时候,再把这个方法给实现就可以实现扩展了。
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
缺点:产品族扩展非常困难,上面我解释的要加一个产品,非常复杂,所以这种模式扩展性不好。
下面贴代码:
//汽车工厂
public interface CarFactory {
//创建引擎对象
Engine createEngine();
//创建座椅对象
Seat createSeat();
//创建轮胎对象
Tyre createTyre();
}
public interface Seat {
void message();
}
//高端座椅
class UpSeat implements Seat{
public void message() {
System.out.println("高端座椅");
}
}
//低端座椅
class LowSeat implements Seat{
public void message() {
System.out.println("低端座椅!");
}
}
public interface Tyre {
void message();
}
//高端轮胎
class UpTyre implements Tyre{
public void message() {
System.out.println("高端轮胎");
}
}
//低端轮胎
class LowTyre implements Tyre{
public void message() {
System.out.println("低端轮胎");
}
}
public interface Engine {
void message();
}
//高端引擎
class UpEngine implements Engine{
public void message() {
System.out.println("高端引擎");
}
}
//低端引擎
class LowEngine implements Engine{
public void message() {
System.out.println("低端引擎");
}
}
下面是我们的工厂类:
/**
* 低端汽车工厂由
* 低端引擎+低端座椅+低端轮胎组成
*
* */
public class LowCarfactory implements CarFactory{
public Engine createEngine() {
return new LowEngine();
}
public Seat createSeat() {
return new LowSeat();
}
public Tyre createTyre() {
return new LowTyre();
}
}
//高端汽车工厂
public class UpCarFactory implements CarFactory{
public Engine createEngine() {
return new UpEngine();
}
public Seat createSeat() {
// TODO Auto-generated method stub
return new UpSeat();
}
public Tyre createTyre() {
return new UpTyre();
}
}
测试类:
public class Client {
public static void main(String[] args) {
//测试低端汽车
CarFactory c = new LowCarfactory();
c.createEngine().message();
c.createSeat().message();
c.createTyre().message();
//测试高端汽车
CarFactory c1 = new UpCarFactory();
c1.createEngine().message();
c1.createSeat().message();
c1.createTyre().message();
}
}
由此我们的汽车就创建成功了,这就是抽象工厂模式。