简单工厂(Simple Factory),最合适的设计模式首秀.

简单工厂又称为静态工厂方法(static factory method)模式,简单工厂是由一个工厂来决定创建出哪一种个体的实现,在很多的讨论中,简单工厂做为工厂方法模式(Factory Method)的一个特殊案例出现.

这个模式封装的变化点是什么?

这是每一个模式都应该考虑的核心问题,一定要记得,如果系统中这个点不会变化,是没必要来封装的,否则会造成模式误用.简单工厂是解决因为多个子类的实例动态创建的问题,变化点也就是:具体的创建实例不确定.

初期状态

既然是对象创建模式,当然解决的是对象创建时的耦合,不是所有的创建对象都是耦合的,我们需要酌情考虑,比如:String str = new String("abc");这样的代码,在系统中是不会变化的,或者变化频率非常的低,不必封装.而我们的业务对象比如一个游戏场景中的道路(Road)希望在运行中选择不同风格的道路,比如有泥泞道路(WaterRoad),雪地道路(SnowRoad),未来还有可能引入各种不同道路,那么我们的初期调用处(Client)代码可能是这样的:

if( roadType.equals("water") )
{
    WaterRoad wroad = new WaterRoad() ;
    //...
}
else if( roadType.equals("snow"))
{
    SnowRoad sroad = new SnowRoad() ;
    //...
}

此时如果要加入新的XXRoad风格对象,我们需要增加一个XXRoad类,然后在调用处(Clinet)代码中修改,增加else if( roadType.eqals("xxroad"))这样的代码.违反了设计模式中的开闭原则(对扩展开放,对修改关闭),我们使用了破坏性的方式来修改这段代码,导致了调用处代码的修改与重新编译.

第一步封装

按照重构的思路,我们上边的代码,因为违反了开闭原则,我们希望在修改代码时不用去修改Client代码,在这里我们引入依赖倒置原则来解决这个问题.

先来看看我们目前的依赖关系,高层模块依赖着低层模块,Client代码就是高层模块,它直接调用着WaterRoad,SnowRoad等对象,这样当对象有变化时,自然是会影响到Client代码.依赖倒置是指,在高层模块与低层模块中加入一层抽象层,两层代码都依赖了抽象层.这样当具体类型需要修改时,不会影响到Client.

解决办法

在上面的例子中,引入Road接口,来描述道路的共同行为,将WaterRoad与SnowRoad实现Road接口.这样一来,调用处的代码就变成了

    Road road = null ;

    if( roadType.equals("water") )
    {
        road = new WaterRoad() ;
        //...
    }
    else if( roadType.equals("snow"))
    {
        road = new SnowRoad() ;
        //...
    }

封装了什么?

至此我们完成了第一步封装,将对象的行为抽象为接口,将变化的不同类型的是现封装到了实现类中.但是Client中的代码还是在if else判断,如果加入新的类型,依然需要修改Client,接下来我们解决第二步封装.

第二步封装

上面提到的问题是要解决Client中的if else判断,我们引进SimpleFactory来封装这个动态判断的过程.

简单工厂(Simple Factory),最合适的设计模式首秀.

/**
 * 道路接口
 *
 * @author aladdinty
 * @create 2017-12-29
 **/
public interface Road
{
}

/**
 * @author aladdinty
 * @create 2017-12-29
 **/
public class SnowRoad implements Road
{
}

/**
 * @author aladdinty
 * @create 2017-12-29
 **/
public class WaterRoad implements Road
{
}

/**
 * 最简单的工厂模式
 *
 * @author aladdinty
 * @create 2017-12-29
 **/
public class SimpleFactory
{
    public static Road createObject(String roadType)
    {
        if( roadType.equals ( "water"))
        {
            return new WaterRoad () ;
        }
        else if( roadType.equals ("snow"))
        {
            return new SnowRoad () ;
        }
        else
        {
            return null ;
        }
    }

    public static void main( String[] args )
    {
        Object obj = SimpleFactory.createObject ("water") ;
    }
}

到目前为止,简单工厂模式就完成了,解决了具体创建的对象类型不确定,当增加新的具体实现时,我们可以增加类的方式来实现,不必修改调用处(Client),当然Factory还需要修改if else代码,这个问题可以用之后的工厂方法模式来解决,或者使用反射技术. 工厂方法模式是专门为了解决factory中的变化而生,反射是将字符串判断消化掉.

上一篇:修改NavigationBar样式


下一篇:js笔记——js数据类型转换