工厂模式的三种实现方式以及优缺点分析
工厂模式:将类的创建对外封闭,对内开放,减少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(); }
创建兰州拉面类:
/** * @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("兰州拉面"); } }
创建新疆拉面类:
/** * @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("新疆拉面"); } }
创建生产面条的简单工厂:
/** * @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(); } } }
使用简单工厂:
/** * @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(); } }
缺点:耦合性还很高
每次要添加一种面条类,工厂就要多加一个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(); }
创建兰州拉面:
/** * @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("兰州拉面"); } }
创建新疆拉面:
/** * @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("新疆拉面"); } }
创建抽象的工厂接口:
/** * @author RestartYang * @Title: ${抽象工厂} * @Package ${package_name} * @Description: ${todo} * @date 2018/5/810:38 */ public interface NoodleFactory { public abstract INoodles create(); }
创建生产兰州拉面的工厂实现类:
/** * @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(); } }
创建生产新疆拉面的工厂实现类:
/** * @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(); } }
使用工厂模式:
/** * @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(); } }
这样一来,每次生产一种新类型的面条,只需要再添加一个工厂就可以了。
耦合性比起简单模式要松很多。
缺点:
这个工厂使用太单一,一种工厂只能生产一种面条,如果要搞特色面馆,就显的力不从心。其实我觉得还好。
抽象工厂模式:
创建面条基类:
/** * @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(); }
创建兰州拉面:
/** * @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("兰州拉面"); } }
创建新疆拉面:
/** * @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("新疆拉面"); } }
创建咸菜基类:
/** * @author RestartYang * @Title: ${file_name} * @Package ${package_name} * @Description: ${todo} * @date 2018/5/910:02 */ public interface XianCai { public void addTaste(); }
创建老干妈咸菜:
/** * @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("老干妈咸菜"); } }
创建工厂抽象接口:
public interface Factory { INoodles createLZNoodles(); XianCai createLGMXianCai(); }
创建工厂实现类:
public class IFactory implements Factory { @Override public INoodles createLZNoodles() { return new LzNoodles(); } @Override public XianCai createLGMXianCai() { return new LGMXianCai(); } }
使用抽象工厂:
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(); } }
依据“产品族”区分工厂,最大限度的进行抽象,可以让这个工厂实现各种花样的功能,但同时每次增加一种类型的工厂,意味这从工厂到产品基类都要跟随变动。
关于最后一个抽象工厂,我可能理解还不到位,有待进一步深究。

浙公网安备 33010602011771号