简单工厂,工厂模式,反射工厂,抽象工厂

在软件设计中,我们通常是追求封装,降低耦合。开放封闭原则是符合这一设计目标的。

开放封闭原则主要体现在:

1.对扩展开放 

2.对修改封闭  

我们通常使用OOP中的多态和继承来实现这个目的。

场景:一个大富翁出行,他拥有很多交通工具,汽车,轮船,飞机。

简单工厂:

将交通工具抽象为一个接口或者抽象类,使实际的交通工具继承或实现它。创造一个简单工厂(我们通常称此工厂为“上帝类”,意味着任何事都需要它负责,它可能除了负责交通工具,还要负责选择着装,负责出行时间,所以这种模式破坏了开放封闭原则中的对扩展开放)

代码如下:

package SimpleFactory;

public class Car implements Vehicle{

    @Override
    public void run() {
        // TODO Auto-generated method stub
        System.out.println("汽车在地上开");
    }

}

public class Plane implements Vehicle{

    public void run() {
        System.out.println("飞机在天上飞");
    }

}


public interface Vehicle {
public  void run();
}

public  class VehicleFactory {
public static Vehicle createVehicle(VehicleType t)
{
    switch (t) {
    case Car:
        return new Car();
    case Plane:
        return new Plane();
    default:
        return null;
    }
}
}

public enum VehicleType {
Car,
Plane
}

测试程序:

using System;
using ParkFactorys;
namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            IFactory factory = new ParkFactoryA();
            IPark park=factory.CreatePark();
            park.GetParkInfo();
            ICar car = factory.CreateCar();
            car.Run();
            Console.ReadLine();
        }
    }
}

当我们有更多同一需求时,(这里指拥有更多交通工具),必须修改上帝类Vehicle.


 

工厂模式

对这种情况进行了改良,我们是否可以创建一个工厂接口,当我们需要添加更多的交通工具时,可以添加不同交通工具工厂来实现此接口?

代码如下:

 

package FactoryMethod;

public class Car implements Vehicle{

    @Override
    public void run() {
        // TODO Auto-generated method stub
        System.out.println("汽车在地上开");
    }

}

public class Plane implements Vehicle{

    public void run() {
        System.out.println("飞机在天上飞");
    }

}

public class CarFactory implements IVehicleFactory{

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

}

public class PlaneFactory implements IVehicleFactory{

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

}


public interface IVehicleFactory {
    Vehicle CreateVehicle();
}


public interface Vehicle {
public void run();
}

 

测试程序如下:

package FactoryMethod;

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        IVehicleFactory iv=new CarFactory();
        Vehicle v=iv.CreateVehicle();
        v.run();
}
}

反射工厂:

反射工厂同样是针对简单工厂破坏开封原则的一种改进,使用Java的反射特性

代码如下:(Car,Plane,Vehicle类同上,这里暂不列举)

package ReflectionFactory;

import java.lang.reflect.*;

public class VehicleFactory {
public static Vehicle CreateVehicle(String typeName) 
{
    try {
        Class clazz=Class.forName(typeName);
        try {
            return(Vehicle)clazz.newInstance();
        } catch (InstantiationException e) {
            // TODO: handle exception
            throw new RuntimeException("实例化异常",e);
        }catch (IllegalAccessException e) {
            // TODO: handle exception
            throw new RuntimeException(e);
        }
    } catch (ClassNotFoundException e) {
        // TODO: handle exception
        throw new RuntimeException("这个实体类不存在",e);
    }
}
}

测试程序:

package ReflectionFactory;

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Vehicle v=VehicleFactory.CreateVehicle("ReflectionFactory.Car");
        v.run();
    }

}

抽象工厂:

场景:当这个富翁选完了交通工具,还要考虑目的地的时候,或者考虑使用什么手机,穿什么衣服的时候,换句话说,涉及多重产品时,我们必须将工厂模式进行扩展,将大富翁今天的单一工厂(选择汽车类)扩展为多重工厂(既能选择汽车,也能选择着装,手机)

代码如下:

package AbstractFactory;

public interface Ball {
public void play();
}

public class BasketBall implements Ball{

    @Override
    public void play() {
        // TODO Auto-generated method stub
        System.out.println("在篮球场上打篮球");
    }

}

package AbstractFactory;

public class FootBall implements Ball{

    @Override
    public void play() {
        // TODO Auto-generated method stub
        System.out.println("在足球场上踢足球");
    }

}

public interface Vehicle {
public  void run();
}

public class Car implements Vehicle{

    @Override
    public void run() {
        // TODO Auto-generated method stub
        System.out.println("汽车在地上开");
    }

}

public class Plane implements Vehicle{

    public void run() {
        System.out.println("飞机在天上飞");
    }

}

public interface IFactory {
  Vehicle createVehicle();
  Ball createBall();
}

public class DefaultFactory implements IFactory{

    @Override
    public Ball createBall() {
        // TODO Auto-generated method stub
        return new FootBall();
    }

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

}

测试程序如下:

package AbstractFactory;

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        IFactory ivFactory=new DefaultFactory();
        Vehicle v=ivFactory.createVehicle();
        Ball b=ivFactory.createBall();
        v.run();
        b.play();
    }

}

当我们既定了富翁今天必须选择交通工具,衣着,目的地三个产品线之后,多重选择工厂IFactory就不用变化,符合开封原则,不过当你需要决定另外的事务时,就必须修改Ifactory类和默认选择类,重新新建一个产品线。


个人认为没有完美匹配任何需求的设计模式,我们必须灵活运用抽象来降低耦合性和封装,尽量使程序的扩展性和封闭性更好。

以上代码经测试无误。

 

posted @ 2016-11-09 17:18  Maskisland  阅读(316)  评论(0编辑  收藏  举报