java设计模式-工厂模式
模式导读:
在现实生活中,我们可能会有过这样一种经历,我想要一台笔记本电脑,但是平常对在实体店里面的笔记本电脑价格不太满意,然后我们就想着去进货的厂里面找,我们不需要关注我们要买的笔记本电脑是怎样生产的,我们只需要一手交钱,一手交货就可以了。这便是工厂方法适用的一种场景,它让我们不需要去关注产品的生产,只需要知道自己需要这种产品即可。
工厂模式:实现了创建者和调用者的分离。
核心本质:
- 实例化对象,用工厂方法代替new操作;
- 将选择实现类,创建对象统一管理和控制,从而将调用者和实现类解耦。
分类:
- 简单工厂模式:也叫静态工厂模式,一般使用静态方法,通过接受的参数的不同返回不同的对象实例,用来生产同意同一等级结构中的任意产品。对于增加新的产品,需要修改已有的代码,违反了开闭原则。
- 工厂方法模式:用来生产同一等级结构中的固定产品。支持增加任意产品。
- 抽象工厂模式:用来生产不同产品族的全部产品,不能增加新的产品,支持增加产品族。
简单工厂模式与工厂模式的区别:
简单工厂模式只有一个(对于一个项目或者一个独立的模块而言)工厂类,而工厂模式有一组实现了相同接口的工厂类。
一:简单工厂模式:
参考类图:
代码实现:
1.抽象产品类,并提供一个抽象方法用于信息显示
1 package com.etc.simplefactory; 2 3 public interface Computer { 4 //定义一个抽象的产品类并给它一个信息显示的方法 5 void showMessage(); 6 }
2.具体的产品类,实现抽象产品类
1 package com.etc.simplefactory; 2 3 public class Lenveno implements Computer { 4 public double price; 5 6 public Lenveno(double price) { 7 this.price=price; 8 } 9 @Override 10 public void showMessage() { 11 System.out.println("这是一台价格为:"+price+"的联想电脑!"); 12 } 13 14 }
1 package com.etc.simplefactory; 2 3 public class Apple implements Computer { 4 public double price; 5 6 public Apple(double price) { 7 this.price=price; 8 } 9 10 @Override 11 public void showMessage() { 12 System.out.println("这是一台价格为:"+price+"的苹果电脑!"); 13 14 } 15 16 }
3.产品工厂类,提供创建产品的方法
1 package com.etc.simplefactory; 2 3 //电脑制造商,制造特定的产品 4 public class ComputerFactory { 5 //制造联想电脑 6 public static Computer createComputer(String msg) { 7 if(msg.equals("联想电脑")) { 8 return new Lenveno(3900); 9 } 10 if(msg.equals("苹果电脑")) { 11 return new Apple(8500); 12 } 13 else 14 return null; 15 } 16 }
4.客户端类,提出需求,给出产品信息
1 package com.etc.simplefactory; 2 3 public class Client { 4 5 public static void main(String[] args) { 6 //客户需要联想电脑 7 Computer lenveno=ComputerFactory.createComputer("联想电脑"); 8 lenveno.showMessage(); 9 //客户需要苹果电脑 10 Computer apple=ComputerFactory.createComputer("苹果电脑"); 11 apple.showMessage(); 12 13 } 14 15 }
效果截图:
二:工厂方法模式:
参考类图:
代码实现:
1.抽象产品类,并提供一个抽象方法用于信息显示
1 package com.etc.simplefactory;
2
3 public interface Computer {
4 //定义一个抽象的产品类并给它一个信息显示的方法
5 void showMessage();
6 }
2.具体的产品类,实现抽象产品类
1 package com.etc.simplefactory;
2
3 public class Lenveno implements Computer {
4 public double price;
5
6 public Lenveno(double price) {
7 this.price=price;
8 }
9 @Override
10 public void showMessage() {
11 System.out.println("这是一台价格为:"+price+"的联想电脑!");
12 }
13
14 }
1 package com.etc.simplefactory;
2
3 public class Apple implements Computer {
4 public double price;
5
6 public Apple(double price) {
7 this.price=price;
8 }
9
10 @Override
11 public void showMessage() {
12 System.out.println("这是一台价格为:"+price+"的苹果电脑!");
13
14 }
15
16 }
3.定义抽象工厂接口,里面定义抽象产品创建方法
1 package com.etc.factory; 2 3 //抽象工厂接口 4 public interface ComputerFactory { 5 //产品生产抽象方法 6 public Computer createComputer(String msg); 7 8 }
4.具体的工厂类,创建对应的产品
1 package com.etc.factory; 2 //具体的联想电脑生产工厂 3 public class LenvenoFactory implements ComputerFactory { 4 5 @Override 6 public Computer createComputer(String msg) { 7 if(msg.equals("联想电脑")) { 8 return new Lenveno(4500); 9 } 10 else 11 return null; 12 } 13 }
1 package com.etc.factory; 2 //苹果电脑具体生产工厂 3 public class AppleFactory implements ComputerFactory { 4 5 @Override 6 public Computer createComputer(String msg) { 7 if(msg.equals("苹果电脑")) { 8 return new Apple(9600); 9 } 10 else 11 return null; 12 } 13 14 }
5.客户端类,根据用户需求给定特定工厂的特定产品
1 package com.etc.factory; 2 3 public class Client { 4 5 public static void main(String[] args) { 6 //客户需要联想电脑 7 Computer lenveno=new LenvenoFactory().createComputer("联想电脑"); 8 lenveno.showMessage(); 9 //客户需要苹果电脑 10 Computer apple=new AppleFactory().createComputer("苹果电脑"); 11 apple.showMessage(); 12 } 13 14 }
效果截图:
工厂模式优缺点:
优点:
1、一个调用者想创建一个对象,只要知道其名称就可以了。
2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
3、屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。
适用场景:
1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。
3、设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。