设计模式之工厂模式
工厂模式是创建型模式的一种,主要目的是提供生产对象的最佳方式。在客户端调用产生对象时屏蔽实例化对象的细节,使得客户端简化对象的实例化过程。在使用工厂模式时一般是考虑到生产某个对象时相对于普通对象有一定的复杂度,在调用时 需要调用者了解生产所需的细节,提高了生产、调用难度,这也是采用工厂模式的原因之一。工厂模式分为了简单工厂模式和工厂方法模式,还有另一种更加复杂的抽象工厂模式。下面我们来看看这几种工厂模式的具体实现:
- 简单工厂模式
package com.wqq.simplefactory; public interface Computer { void cpu(); } class Lenovo implements Computer{ @Override public void cpu() { System.out.println("Lenovo.cpu()"); } } class Samsung implements Computer{ @Override public void cpu() { System.out.println("Samsung.cpu()"); } } class ASUS implements Computer{ @Override public void cpu() { System.out.println("ASUS.cpu()"); } }
我们这里的简单工厂模式以生产电脑为例,首先我们定义了电脑的接口Computer,然后分别用三个牌子的电脑实现了这个接口,以生产不同品牌的电脑。
public class ComputerFactory { public Computer createComputer(String type) { if(type==null) { return null; } if(type.equals("联想")) { return new Lenovo(); }else if(type.equals("华硕")) { return new ASUS(); }else if(type.equals("三星")) { return new Samsung(); } return null; } }
这里创建了生产电脑的工厂类,根据不同的类型来生产所需的不同品牌的电脑,但是很显然这里违背了设计模式的六大原则之一的开闭原则,如何需要添加新的品牌的话就必须修改原有的代码,这也是后面工厂方法模式所主要处理的问题。
public class Client { public static void main(String[] args) { Computer computer1 = new ComputerFactory().createComputer("华硕"); Computer computer2 = new ComputerFactory().createComputer("联想"); Computer computer3 = new ComputerFactory().createComputer("三星"); computer1.cpu(); computer2.cpu(); computer3.cpu(); } }
最后是client客户端测试类,我们只要实例化工厂类并调用生产电脑的方法传入参数即可获得我们想要的电脑,生产不同的电脑我们所需关注的细节变少了,如果生产电脑的具体实现细节复杂,我们也不用过多的关心细节,只要少量的参数和知道相应的方法即可获取到想要的对象,简化了开发过程。
- 工厂方法模式
package com.wqq.factorymethod; public interface Computer { void cpu(); } class Lenovo implements Computer{ @Override public void cpu() { System.out.println("Lenovo.cpu()"); } } class Samsung implements Computer{ @Override public void cpu() { System.out.println("Samsung.cpu()"); } } class ASUS implements Computer{ @Override public void cpu() { System.out.println("ASUS.cpu()"); } }
这里同样的声明Computer接口并有相应的实现类实现。
public class ASUSFactory { public ASUS createASUS() { return new ASUS(); } }
public class LenovoFactory { public Lenovo createLenovo() { return new Lenovo(); } }
public class SamsungFactory { public Samsung createSamsung() { return new Samsung(); } }
然后通过不同的工厂创建具体的品牌电脑。
public class Client { public static void main(String[] args) { Computer computer1 = new ASUSFactory().createASUS(); Computer computer2 = new LenovoFactory().createLenovo(); Computer computer3 = new SamsungFactory().createSamsung(); computer1.cpu(); computer2.cpu(); computer3.cpu(); } }
client客户端中可以看到通过不同的工厂创建不同的对象。从代码上我们可以发现,工厂方法模式是使用了具体的工厂来生产某个想要的对象,跟简单工厂模式相比粒度更细,同时改善了简单工厂模式中开闭原则的问题并体现了单一职责原则,但这也同样带来了问题:那就是如果需要生产的对象多的话,难免造成代码的冗余以及调用者的不便,并且有陷入“过度设计”的嫌疑,因此这不是我们具体生产环境中的最佳实践,还需要考虑具体的生产环境再做判断。
- 抽象工厂模式
package com.wqq.abstractfactory; public interface Cpu{ void version(); } class goodCpu implements Cpu{ @Override public void version() { System.out.println("intel i7"); } } class lowCpu implements Cpu{ @Override public void version() { System.out.println("intel i5"); } }
package com.wqq.abstractfactory; public interface Disk { void type(); } class goodDisk implements Disk{ @Override public void type() { System.out.println("固态硬盘"); } } class lowDisk implements Disk{ @Override public void type() { System.out.println("机械硬盘"); } }
package com.wqq.abstractfactory; public interface RAM { void size(); } class goodRAM implements RAM{ @Override public void size() { System.out.println("16G"); } } class lowRAM implements RAM{ @Override public void size() { System.out.println("4G"); } }
public interface ComputerFactory { Cpu getCpu(); Disk getDisk(); RAM getRAM(); }
public class GoodComputerFactroy implements ComputerFactory{ @Override public Cpu getCpu() { // TODO Auto-generated method stub return new goodCpu(); } @Override public Disk getDisk() { // TODO Auto-generated method stub return new goodDisk(); } @Override public RAM getRAM() { // TODO Auto-generated method stub return new goodRAM(); } }
public class LowComputerFactory implements ComputerFactory { @Override public Cpu getCpu() { // TODO Auto-generated method stub return new lowCpu(); } @Override public Disk getDisk() { // TODO Auto-generated method stub return new lowDisk(); } @Override public RAM getRAM() { // TODO Auto-generated method stub return new lowRAM(); } }
public class Client { public static void main(String[] args) { ComputerFactory factory = new GoodComputerFactroy(); ComputerFactory factory1 = new LowComputerFactory(); Cpu goodCpu = factory.getCpu(); Cpu lowCpu = factory1.getCpu(); goodCpu.version(); lowCpu.version(); } }
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。在这里我们我们先创建了三个小部件的接口:cpu、ram、disk,随后它们的实现类(goodClass,lowClass)分别实现这三个接口,然后我们有一个抽象的工厂ComputerFactory,该工厂下有两个实现了该接口的工厂,分别为GoodComputerFactory和LowComputerFactroy用以生产好的电脑和低端电脑。从测试类可以看出,抽象工厂就是个生产工厂的大工厂,生产完工厂后,再让工厂去生产具体的“零部件”。