工厂模式:关于一个工厂的故事
关于一个工厂的故事
话说有一个生产电视机的工厂,可以生产海信电视机、海尔电视机。程序设计如下:
/*** 电视机工厂* @author zherop*/
public class TVFactory {/*** 生产海尔电视机** @return*/public HaierTV createHaierTV() {return new HaierTV();}/*** 生产海信电视机** @return*/public HisenseTV createHisenseTV() {return new HisenseTV();}
}/*** 海尔电视机* @author zherop*/
public class HaierTV {public void play() {System.out.println("海尔电视机播放...");}
}/*** 海信电视机* @author zherop*/
public class HisenseTV {public void play() {System.out.println("海信电视机播放...");}
}
一切都是那么美好,随着工厂业务的发展,现在又需要生产华为电视机。这个时候,厂长找到工程师小曾,让他给出个设计方案。
于是小曾稍作思考,并想到如下方案:
新增 HuaweiTV,然后修改 TVFactory
/*** 华为电视机* @author zherop*/
public class HuaweiTV {public void play() {System.out.println("华为电视机播放...");}
}public class TVFactory {/*** 生产华为电视机* @return*/public HuaweiTV createHuaweiTV() {return new HuaweiTV();}
}
咋一看,这么设计还挺自然的。小曾又想了想,似乎不太对,新增了一个品牌的电视机,就需要去整改一直运作良好的工厂,心想,万一整改的过程中,不小心影响了其他产品线咋办?
于是,小曾陷入沉思,电视机要定一个标准,然后针对这个标准,工厂产品线就可以生产出来,于是乎,方案变成了这样:
电视机标准:
public interface TV {public void play();
}
所有品牌电视机都遵循这个标准:
/*** 海尔电视机* @author zherop*/
public class HaierTV implements TV {public void play() {System.out.println("海尔电视机播放...");}
}/*** 海信电视机* @author zherop*/
public class HisenseTV implements TV {public void play() {System.out.println("海信电视机播放...");}
}/*** 华为电视机* @author zherop*/
public class HuaweiTV implements TV {public void play() {System.out.println("华为电视机播放...");}
}
工厂产品线改造:
/*** 电视机工厂* @author zherop*/
public class TVFactory {/*** 生产电视机** @return*/public <T extends TV> TV createTV(Class<T> tv) {try {return tv.newInstance();} catch (Exception e) {e.printStackTrace();System.out.println("生产过程中发生故障!");}return null;}
}
工厂生产测试:
public class Client {public static void main(String[] args) {TVFactory tvFactory = new TVFactory();// 生产海尔电视机TV tv = tvFactory.createTV(HaierTV.class);// 测试电视机是否正常工作tv.play();}
}
这样,即使以后再接其他品牌的单,工厂也不用改造了。小曾顿时心情愉悦,很有成就感。
就这样,靠着这个万能的产品线,工厂稳步发展…
随着科技的进步,开始出现了新型的电视机——智慧屏。智慧屏的生产比普通电视机要复杂得多,工厂现在的设计已经不能满足需求了,厂长又开始着急了,不接这个单?那显示是不可能,如果不更新换代,工厂迟早会淘汰。于是厂长又找到了小曾。
小曾思考了下,很自然地想到了把生成电视机的产品线改造下:
/*** 电视机工厂* @author zherop*/
public class TVFactory {/*** 生产电视机* * @return*/public <T extends TV> TV createTV(Class<T> tv) {try {T product = tv.newInstance();// 如果是智慧屏,特殊加工处理if (tv.getSimpleName().equals("HonorSmartTV")) {processSmartTV(product);}return product;} catch (Exception e) {e.printStackTrace();System.out.println("生产过程中发生故障!");}return null;}private void processSmartTV(TV product) {System.out.println("智慧屏加工!");}
}/*** 荣耀智慧屏* @author zherop*/
public class HonorSmartTV implements TV {public void play() {System.out.println("荣耀智慧屏播放...");}
}
小曾又想了想,咋又要动现有的产品线?不得行,不得行!现在虽然轻松,以后要是再出现其他新型电视机,又要改动,老是改来改去,迟早要出事!
经过一番苦想,既然电视生产的具体流程没法统一,何不建造新的工厂,由特定的工厂来针对性地生产特定的电视机呢?又想到了如下方案:
要建立多个工厂,那么就需要有工厂的标准,工厂是用来生产电视机,而不是来干其他事情的。
电视机工厂建设标准:
/*** 电视机工厂* @author zherop*/
public interface TVFactory {/*** 生产电视机* * @return*/public TV createTV();
}
建造具体工厂:
/*** 海尔电视机工厂* @author zherop*/
public class HaierTVFacatory implements TVFactory {public TV createTV() {return new HaierTV();}
}/*** 海信电视机工厂* @author zherop*/
public class HisenseTVFactory implements TVFactory {public TV createTV() {return new HisenseTV();}}/*** 荣耀智慧屏工厂* @author zherop*/
public class HonorSmartTVFactory implements TVFactory {public TV createTV() {return new HonorSmartTV();}}
测试:
public class Client {public static void main(String[] args) {// 使用荣耀智慧屏工厂TVFactory tvFactory = new HonorSmartTVFactory();TV tv = tvFactory.createTV();// 测试电视机是否正常工作tv.play();}
}
嘿嘿,小曾心想,这样工厂以后灵活性很高了,无论科技怎么发展,工厂都能轻松应对。
看到这儿,故事就差不多结束了,至此工厂方法模式也讲得差不多了,各种变体也蕴含其中。设计模式虽是招式,但是需要根据不同的场景,进行灵活变动,不能太死板了。
定义
工厂方法模式定义:工厂方法模式又称工厂模式,工厂父类负责定义创建产品对象的公共接口,而工程子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。
涉及的角色:
-
抽象产品(Product)
抽象产品是定义产品的接口。比如故事中的TV类。 -
具体产品(ConcreteProduct)
具体产品实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,它们之间一一对应。比如故事中的HisenseTV、HonorSmartTV、HaierTV类。 -
抽象工厂(Factory)
在抽象工厂类中,声明了工厂方法,用于返回一个产品。比如故事中的TVFactory类。 -
具体工厂(ConcreteFactory)
具体工厂类是抽象工厂类的子类,实现了抽象工厂中定义的工厂方法,并可由客户端调用,返回一个具体产品类的实现。比如故事中的HisenseTVFactory、HonorSmartTVFactory类。
类图:

工厂方法模式,扩展性非常好,符合开闭原则,是典型的解耦框架。高层模块只需要知道产品的抽象类,其他实现类都不需要关心,符合迪米特法则;只依赖于产品类的抽象,符合依赖倒置原则;也符合里氏代换原则。
理论上,工厂方法模式在所有需要生成对象的地方都可以使用,但是需要考虑是否要增加一个工厂类来进行管理,毕竟会增加代码的复杂度。

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
