应用最广泛的工厂模式
来源:互联网 发布:linux 怎么引导win 7 编辑:程序博客网 时间:2024/05/21 18:36
工厂
事例:
某公司下有多条生产线,都是生产鸭脖。但鸭脖有酱香的,有麻辣的,有五香的,有原味的。每条生产线生产一种鸭脖,而鸭脖又对应不同味道即不同商标。对于忙碌的领导来说,他需要知道所有生产线吗和所有鸭脖吗?那样的话要记录的事也太多了,越来越多的生产线和鸭脖味道就会越来越复杂。对应在程序中也是如此,领导只需要关心有生产线生产鸭脖,鸭脖有味道就可以了。用得最多的模式,工厂模式来表述上面事例。
抽象工厂和抽象产品
基于面向对象的思想,首先定义一个生产线接口,它有一个实现生产鸭脖的方法。再定义一个鸭脖接口,它有一个味道的方法。
public interface IProductLineFactory{ IDuckNeck createDuckNeck();}public interface IDuckNeck{ void taste();}
实际工厂和实际产品
我们假设要找产原味鸭脖的生产线生产原味鸭脖。
public class NormalProductLineFactory implements IProductLineFactory{ @Override public IDuckNeck createDuckNeck(){ return new NormalTasteDuckNeck(); }}public class NormalTasteDuckNeck implements IDuckNeck { @Override public void taste(){ System.out.printls("这里是原味鸭脖哦"); }}
然后我们想要获取看看鸭脖味道:
public class Test{ public static void main(String[] args){ IProductLineFactory factory=new NormalProductLineFactory(); IDuckNeck duckneck=factory.createDuckNeck(); duckneck.taste(); }}
这里几个角色也很简单,主要四大模块:
- 抽象工厂:这就是工厂方法的核心
- 具体工厂:实现具体的业务逻辑,生产具体的产品。
- 抽象产品:产品的父类,描述产品该有的行为。
- 具体产品:抽象产品具体产品的对象,实现具体行为。
要找另外的生产线生产另外味道的鸭脖,也可以轻而易举的就执行了。对于领导只需要知道生产线生产鸭脖,鸭脖有自己的味道就可以了。如果想得到麻辣味鸭脖,只需要更改工厂实现逻辑即可,返回麻辣味鸭脖就可以了。
当然这种方式,我们需要创建更多的工厂具体类,所以也是挺麻烦的,通常我们可以通过自己喜欢的方式来不重复创建工厂类:
实际使用工厂方式
反射创建
public interface IProductLineFactory{ /** * 抽象工厂方法 * @param clz 产品对象类型 * @return 具体产品对象 */ <T extends IDuckNeck> T createDuckNeck(Class<T> clz);}
对于具体工厂类,我们可以通过反射获取类的实例:
public class ConcreteFactory implements IProductLineFactory{ public <T extends IDuckNeck> T createDuckNeck(Class<T> clz){ IDuckNeck duckneck; try{ duckneck=(IDuckNeck)Class.forName(clz.getName()).newInstance(); }catch(Exception e){ } return duckneck; }}
再来看下测试:
public class Test{ public static void main(String[] args){ IProductLineFactory factory=new ConcreteFactory(); IDuckNeck duckneck=factory.createDuckNeck(NormalTasteDuckNeck.class); duckneck.taste(); }}
这是一种方式,通过反射就不用反复创建具体工厂了,当然反射效率稍微要低一点,所以还是可以有其他方式实现。
实现方式看具体业务逻辑需求,如果工厂只有一个,可以直接用静态工厂,来去掉抽象工厂类。
静态工厂:
public class ConcreteFactory{ public static IDuckNeck createDuckNeck(){ return new NormalTasteDuckNeck(); }}
静态工厂是工厂方式的一种弱化,就直接简化掉了抽象工厂类,如果产品类型不是很多,还可以在抽象工厂类中加入Type类型,来做一个switch取出直接产品类型。
抽象工厂
事例
夏天来了,我们都爱喝饮料,比如某快线和某矿泉水。某快线由饮料部分是乳白色。而矿泉水是透明色,某快线盖子是橙色,矿泉水盖子是白色。身体部分均由软塑料瓶组成。
那么换到我们代码世界中来,不就对应了可替换模块不同实现和实现下组成部分的不同,将组成部分抽象,将每一个组成部分看作一个产品。
抽象工厂
- 先定义一个抽象饮料:
public abstract class DrinkFactory{ /** * 生产液体 * return 液体部分 */ public abstract ILiquid createLiquid(); /** * 生产盖子 * return 盖子部分 */ public abstract ICap createCap(); /** * 生产瓶子 * 因为两个产品瓶子一样,所以可以Up Method 到父类中,如果子类需要改变则自己重写就好 */ protect void createBottle(){ System.out.println("瓶身是熟料瓶身"); }}
- 液体相关类
public interface ILiquid{ void liquid();}public class TransparencyLiquid implements ILiquid{ @Override public void liquid(){ System.out.println("透明液体"); }}public class LacteLiquid implements ILiquid{ @Override public void liquid(){ System.out.println("乳白色液体"); }}
- 盖子相关类
public interface ICap{ void cap();}public class OrangeCap implements ICap{ @Override public void cap(){ System.out.println("橙色盖子"); }}public class WhiteCap implements ICap{ @Override public void cap(){ System.out.println("白色盖子"); }}
声明完了之后,具体工厂就出来了:
- 具体工厂类:
public class XXQX extends DrinkFactory{ /** * 生产液体 * return 液体部分 */ @Override public ILiquid createLiquid(){ return new LacteLiquid(); } /** * 生产盖子 * return 盖子部分 */ @Override public ICap createCap(){ return new OrangeCap(); }}public class XXMineralWater extends DrinkFactory{ /** * 生产液体 * return 液体部分 */ @Override public ILiquid createLiquid(){ return new TransparencyLiquid(); } /** * 生产盖子 * return 盖子部分 */ @Override public ICap createCap(){ return new WhiteCap(); }}
测试:
public class Test{ public static void main(String[] args){ DrinkFactory factoryMineralWater=new XXMineralWater(); factoryMineralWater.createLiquid().liquid(); factoryMineralWater.createCap().cap(); factoryMineralWater.createBottle(); System.out.println("-------"); DrinkFactory factoryQX=new XXQX(); factoryQX.createLiquid().liquid(); factoryQX.createCap().cap(); factoryQX.createBottle(); }}
就这样就把一个饮料给拆分了,组成部分也为产品,我们也可以抽象出来,当其他饮料需要用到的时候可以直接使用,扩展性更好了。
这里用的抽象类,有一个好处就是提升了公共部分,重构的时候,往往会用到此方式,UP Method。就像这里的瓶身
总结
例子1是鸭脖,例子2是饮料,其都是工厂生产产品,而产品具体实现交由产品自己实现。在项目中是一个可替换模块(工厂),对应行为也可替换(产品),但实现不同,将组成部分抽象。
工厂模式是完全符合设计原则的,依赖与抽象的架构,将具体操作交由对应的子类完成,有非常好的扩展性。很多一些使扩展性好的设计模式,比如策略,状态等也都能看到工厂模式的影子。工厂模式不愧为应用最广泛的设计模式
- 应用最广泛的工厂模式
- 设计模式之工厂模式——应用最广泛的模式
- 工厂方法模式——应用最广泛
- 设计模式之单例模式——应用最广泛的设计模式
- 应用广泛的C++单例模式
- 2、使用最广泛的模式-单例模式
- 世界上应用最广泛的虚拟机是啥?
- 盘点7款应用最广泛的 Linux 桌面环境
- 盘点7款应用最广泛的 Linux 桌面环境
- Jquery简单过滤选择器(应用最广泛的选择器)
- 嵌入linux 的广泛应用
- 即时通讯的行业广泛应用
- 工厂模式的应用实例
- 设计模式思想还远未广泛应用
- 计算机信息管理是目前计算机应用最广泛的一个领域
- 广泛应用
- 有可能得到最广泛的利润率
- 使用最广泛的Java库
- java集合(二)——集合 Set
- 计算机图形学知识点
- ios-异步发送网络请求
- Leetcode 650. 2 Keys Keyboard
- 变态跳台阶(剑指Offer)
- 应用最广泛的工厂模式
- java集合(三)——集合 List
- poj 2528 Mayor's posters 线段树成段更新+离散化
- 序列化和反序列化的简单理解
- ioFile
- 如何安装jQuery?
- 生产者/消费者
- (转)知乎:一文读懂比特币私钥、公钥、钱包地址的来历和关系
- springMVC上传图片