工厂模式的三种实现方式以及优缺点分析

工厂模式:将类的创建对外封闭,对内开放,减少new的使用,降低程序的耦合。

简单工厂模式:

创建面条抽象基类:

/**
 * @author RestartYang
 * @Title: ${简单工厂的基类}
 * @Package ${package_name}
 * @Description: ${todo}
 * @date 2018/5/810:19
 */
public abstract class INoodles {
    /**
     * @Description: ${描述面条}
     * @param ${tags}
     * @return ${return_type}
     * @throws
     * @author RestartYang
     * @date 2018/5/8 10:20
     */
    public abstract void  desc();
}
View Code

创建兰州拉面类:

/**
 * @author RestartYang
 * @Title: ${兰州拉面}
 * @Package ${package_name}
 * @Description: ${todo}
 * @date 2018/5/810:21
 */
public class LzNoodles extends INoodles{
    @Override
    public void desc() {
        System.out.println("兰州拉面");
    }
}
View Code

创建新疆拉面类:

/**
 * @author RestartYang
 * @Title: ${新疆拉面}
 * @Package ${package_name}
 * @Description: ${todo}
 * @date 2018/5/810:22
 */
public class XjNoodles extends INoodles{

    @Override
    public void desc() {
        System.out.println("新疆拉面");
    }
}
View Code

创建生产面条的简单工厂:

/**
 * @author RestartYang
 * @Title: ${简单工厂}
 * @Package ${package_name}
 * @Description: ${todo}
 * @date 2018/5/810:25
 */
public class SimpleNoodleFactory {
    static final int TYPE_LZ = 1;
    static final int TYPE_XJ = 2;
    static final int TYPE_PM = 3;

    public static INoodles getNoodles(int type){
        switch (type){
            case TYPE_LZ:
                return new LzNoodles();
            case TYPE_XJ:
                return new XjNoodles();
            case TYPE_PM:
            default:
                return new PMNoodles();
        }
    }
}
View Code

使用简单工厂:

/**
 * @author RestartYang
 * @Title: ${使用简单工厂的案例}
 * @Package ${package_name}
 * @Description: ${todo}
 * @date 2018/5/810:29
 */
public class SimpleFactoryDemo {
    public static void main(String[] args) {
        //点一份面条,兰州拉面
        INoodles noodles = SimpleNoodleFactory.getNoodles(SimpleNoodleFactory.TYPE_LZ);
        noodles.desc();
        //点一份面条,新疆拉面
        INoodles iNoodles = SimpleNoodleFactory.getNoodles(SimpleNoodleFactory.TYPE_XJ);
        iNoodles.desc();
    }
}
View Code

缺点:耦合性还很高

每次要添加一种面条类,工厂就要多加一个type。导致这个工厂类会变得非常繁重,甚至加入的这个type也可能再有变动。

日积月累,代码几经易手,维护起来就会非常麻烦。

工厂方法模式:

创建面条抽象类:

/**
 * @author RestartYang
 * @Title: ${面条的基类}
 * @Package ${package_name}
 * @Description: ${todo}
 * @date 2018/5/810:19
 */
public abstract class INoodles {
    /**
     * @Description: ${描述面条}
     * @param ${tags}
     * @return ${return_type}
     * @throws
     * @author RestartYang
     * @date 2018/5/8 10:20
     */
    public abstract void  desc();
}
View Code

创建兰州拉面:

/**
 * @author RestartYang
 * @Title: ${兰州拉面}
 * @Package ${package_name}
 * @Description: ${todo}
 * @date 2018/5/810:21
 */
public class LzNoodles extends INoodles {
    @Override
    public void desc() {
        System.out.println("兰州拉面");
    }
}
View Code

创建新疆拉面:

/**
 * @author RestartYang
 * @Title: ${新疆拉面}
 * @Package ${package_name}
 * @Description: ${todo}
 * @date 2018/5/810:22
 */
public class XjNoodles extends INoodles {

    @Override
    public void desc() {
        System.out.println("新疆拉面");
    }
}
View Code

创建抽象的工厂接口:

/**
 * @author RestartYang
 * @Title: ${抽象工厂}
 * @Package ${package_name}
 * @Description: ${todo}
 * @date 2018/5/810:38
 */
public interface NoodleFactory {

    public abstract INoodles create();
}
View Code

创建生产兰州拉面的工厂实现类:

/**
 * @author RestartYang
 * @Title: ${兰州拉面工厂}
 * @Package ${package_name}
 * @Description: ${todo}
 * @date 2018/5/810:42
 */
public class LZNoodlesFactory implements NoodleFactory {
    @Override
    public INoodles create() {
        return new LzNoodles();
    }
}
View Code

创建生产新疆拉面的工厂实现类:

/**
 * @author RestartYang
 * @Title: ${新疆拉面工厂}
 * @Package ${package_name}
 * @Description: ${todo}
 * @date 2018/5/810:44
 */
public class XJNoodlesFactory implements NoodleFactory{
    @Override
    public INoodles create() {
        return new XjNoodles();
    }
}
View Code

使用工厂模式:

/**
 * @author RestartYang
 * @Title: ${使用工厂方法}
 * @Package ${package_name}
 * @Description: ${todo}
 * @date 2018/5/810:45
 */
public class FactoryMethodDemo {
    public static void main(String[] args) {
        //让兰州拉面工厂生产一份兰州拉面
        NoodleFactory factory = new LZNoodlesFactory();
        INoodles iNoodles = factory.create();
        iNoodles.desc();
        //让新疆拉面工厂生产一份新疆拉面
        factory = new XJNoodlesFactory();
        INoodles iNoodles1 = factory.create();
        iNoodles1.desc();
    }
}
View Code

这样一来,每次生产一种新类型的面条,只需要再添加一个工厂就可以了。

耦合性比起简单模式要松很多。

缺点:

这个工厂使用太单一,一种工厂只能生产一种面条,如果要搞特色面馆,就显的力不从心。其实我觉得还好。

抽象工厂模式:

创建面条基类:

/**
 * @author RestartYang
 * @Title: ${面条的基类}
 * @Package ${package_name}
 * @Description: ${todo}
 * @date 2018/5/810:19
 */
public abstract class INoodles {
    /**
     * @Description: ${描述面条}
     * @param ${tags}
     * @return ${return_type}
     * @throws
     * @author RestartYang
     * @date 2018/5/8 10:20
     */
    public abstract void  desc();
}
View Code

创建兰州拉面:

/**
 * @author RestartYang
 * @Title: ${兰州拉面}
 * @Package ${package_name}
 * @Description: ${todo}
 * @date 2018/5/810:21
 */
public class LzNoodles extends INoodles {
    @Override
    public void desc() {
        System.out.println("兰州拉面");
    }
}
View Code

创建新疆拉面:

/**
 * @author RestartYang
 * @Title: ${新疆拉面}
 * @Package ${package_name}
 * @Description: ${todo}
 * @date 2018/5/810:22
 */
public class XjNoodles extends INoodles {

    @Override
    public void desc() {
        System.out.println("新疆拉面");
    }
}
View Code

创建咸菜基类:

/**
 * @author RestartYang
 * @Title: ${file_name}
 * @Package ${package_name}
 * @Description: ${todo}
 * @date 2018/5/910:02
 */
public interface XianCai {
    public void addTaste();
}
View Code

创建老干妈咸菜:

/**
 * @author RestartYang
 * @Title: ${file_name}
 * @Package ${package_name}
 * @Description: ${todo}
 * @date 2018/5/910:07
 */
public class LGMXianCai implements XianCai {
    @Override
    public void addTaste() {
        System.out.println("老干妈咸菜");
    }
}
View Code

创建工厂抽象接口:

public interface Factory {
     INoodles createLZNoodles();
     XianCai createLGMXianCai();
}
View Code

创建工厂实现类:

public class IFactory implements Factory {
    @Override
    public INoodles createLZNoodles() {
        return new LzNoodles();
    }

    @Override
    public XianCai createLGMXianCai() {
        return new LGMXianCai();
    }
}
View Code

使用抽象工厂:

public class AbstractFactoryDemo {
    public static void main(String[] args) {
        Factory factory = new IFactory();
        INoodles lzNoodles = factory.createLZNoodles();
        lzNoodles.desc();
        XianCai xianCai = factory.createLGMXianCai();
        xianCai.addTaste();
    }
}
View Code

依据“产品族”区分工厂,最大限度的进行抽象,可以让这个工厂实现各种花样的功能,但同时每次增加一种类型的工厂,意味这从工厂到产品基类都要跟随变动。

关于最后一个抽象工厂,我可能理解还不到位,有待进一步深究。

 

posted @ 2018-05-09 11:04  一介書生  阅读(2343)  评论(0)    收藏  举报