一.何为工厂模式
工厂模式可以分为三类:
1)简单工厂模式(Simple Factory)
2)工厂方法模式(Factory Method)
3)抽象工厂模式(Abstract Factory)
这三种模式从上到下逐步抽象,并且更具一般性。
GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。
将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。
区别
工厂方法模式:一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
两者皆可。
(以上转自http://blog.youkuaiyun.com/jason0539/article/details/23020989)
个人总结:
笔者一开始就是把这几个模式搞混了,通过阅读这篇博客才分清楚各自的区别,简而言之,区别这两种模式的要点就是抽象工厂与抽象产品的数目,若都为1,则是工厂方法模式,若大于1,则是抽象工厂模式。下述代码示例为工厂方法模式。同样也是用MVC架构来实现。
二.为何需要工厂模式
三.代码实例
Model模块(也就是产品部分)
接口Update:作用是通过接口回掉将更新消息传递给界面
public interface Update {
public void update(String att);
}
抽象产品数
public abstract class Num {
public abstract int getNum();
public abstract String getAttribute();
}
具体产品类奇数
public class OddNum extends Num{
private int num;
private String att;
private Update upt;
public OddNum(int i,Update up)
{
num=i;
att=new String("是一个奇数");
upt=up;
upt.update(att);
}
public int getNum()
{
return num;
}
public String getAttribute()
{
return att;
}
}
具体产品类偶数
public class EvenNum extends Num{
private int num;
private String att;
private Update upt;
public EvenNum(int i,Update up)
{
num=i;
att=new String("是一个偶数");
upt=up;
upt.update(att);
}
public int getNum()
{
return num;
}
public String getAttribute()
{
return att;
}
}
抽象工厂类
public abstract class Factory {
public abstract Num CreateNum(int i,Update up);
}
具体工厂类奇数工厂
public class OddFactory extends Factory {
public Num CreateNum(int i,Update up)
{
return new OddNum(i,up);
}
}
具体工厂类偶数工厂
public class EvenFactory extends Factory{
public Num CreateNum(int i,Update up)
{
return new EvenNum(i,up);
}
}
Controller模块(可进行创建num于选择视图等操作)
import javax.swing.JFrame;
public class FacCon {
private Num NUM;
private NumView1 VIEW1;
private NumView2 VIEW2;
private EvenFactory efac;
private OddFactory ofac;
private int mode;//视图模式选择
public FacCon()
{
efac=new EvenFactory();
ofac=new OddFactory();
}
public void setMode(int i)//设置视图模式,1为界面,2为控制台
{
mode=i;
}
public void CreateNum(int num)
{
if(num%2==0)
{
if(mode==1)
NUM=efac.CreateNum(num,VIEW1);
else
NUM=efac.CreateNum(num,VIEW2);
}
else
{
if(mode==1)
NUM=ofac.CreateNum(num,VIEW1);
else
NUM=ofac.CreateNum(num,VIEW2);
}
}
public int getNum()
{
return NUM.getNum();
}
public String getAttribute()
{
return NUM.getAttribute();
}
public void Judge()//由于工厂已经选择好建立奇偶对象,所以不需进行多余的判别
{
}
public void ShowView()
{
switch(mode){
case 1:
{
VIEW1=new NumView1(this);
VIEW1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
VIEW1.setSize(450,120);
VIEW1.setVisible(true);
break;
}
case 2:
{
VIEW2=new NumView2(this);
VIEW2.show();
break;
}
default :System.out.println("设置视图模式错误");
}
}
}
View模块
界面模式
import java.awt.Container;
import javax.swing.JFrame;
import java.awt.FlowLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
public class NumView1 extends JFrame implements Update {
/**
*
*/
private static final long serialVersionUID = 1L;
private FacCon CONTROL;
private boolean HasChange=false;
private String Att;
public NumView1(FacCon Con)
{
super("奇偶判断");
CONTROL=Con;
Container c=getContentPane();//创建面板
c.setLayout(new FlowLayout());
JTextField DisNum=new JTextField("数字:",8);
DisNum.setEditable(false);
JTextField Num=new JTextField(8);//用于输入数字
Num.setEditable(true);
JButton Judge=new JButton("判断");
JTextField Display=new JTextField(8); //显示判断结果
Display.setEditable(false);
c.add(DisNum);
c.add(Num);
c.add(Judge);
c.add(Display);
Judge.addMouseListener(new MouseListener(){
public void mouseClicked(MouseEvent e)
{
String _num=Num.getText();
CONTROL.CreateNum(Integer.parseInt(_num));
CONTROL.Judge();
if(HasChange==true)
{
Display.setText(Att);
HasChange=false;
}
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
});
}
public void update(String att)
{
HasChange=true;
Att=att;
}
}
import java.awt.Container;
import javax.swing.JFrame;
import java.awt.FlowLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
public class NumView1 extends JFrame implements Update {
/**
*
*/
private static final long serialVersionUID = 1L;
private FacCon CONTROL;
private boolean HasChange=false;
private String Att;
public NumView1(FacCon Con)
{
super("奇偶判断");
CONTROL=Con;
Container c=getContentPane();//创建面板
c.setLayout(new FlowLayout());
JTextField DisNum=new JTextField("数字:",8);
DisNum.setEditable(false);
JTextField Num=new JTextField(8);//用于输入数字
Num.setEditable(true);
JButton Judge=new JButton("判断");
JTextField Display=new JTextField(8); //显示判断结果
Display.setEditable(false);
c.add(DisNum);
c.add(Num);
c.add(Judge);
c.add(Display);
Judge.addMouseListener(new MouseListener(){
public void mouseClicked(MouseEvent e)
{
String _num=Num.getText();
CONTROL.CreateNum(Integer.parseInt(_num));
CONTROL.Judge();
if(HasChange==true)
{
Display.setText(Att);
HasChange=false;
}
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
});
}
public void update(String att)
{
HasChange=true;
Att=att;
}
}控制台模式
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class NumView2 implements Update{
private FacCon CONTROL;
private boolean HasChange=false;
private String Att;
public NumView2(FacCon Con) {
CONTROL=Con;
}
public void show(){
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
String _num;
try
{
do{
_num=in.readLine();
if(Integer.parseInt(_num)!=-1)
{
CONTROL.CreateNum(Integer.parseInt(_num));//对对象进行相关处理
CONTROL.Judge();// 判断并设置属性
if(HasChange==true)
{
System.out.println(CONTROL.getAttribute());
HasChange=false;
}
}
}while(Integer.parseInt(_num)!=-1);
System.out.println("结束");
}
catch(IOException e)
{
System.out.println(e.getMessage());
e.printStackTrace();
}
}
public void update(String att)
{
HasChange=true;
Att=att;
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class NumView2 implements Update{
private FacCon CONTROL;
private boolean HasChange=false;
private String Att;
public NumView2(FacCon Con) {
CONTROL=Con;
}
public void show(){
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
String _num;
try
{
do{
_num=in.readLine();
if(Integer.parseInt(_num)!=-1)
{
CONTROL.CreateNum(Integer.parseInt(_num));//对对象进行相关处理
CONTROL.Judge();// 判断并设置属性
if(HasChange==true)
{
System.out.println(CONTROL.getAttribute());
HasChange=false;
}
}
}while(Integer.parseInt(_num)!=-1);
System.out.println("结束");
}
catch(IOException e)
{
System.out.println(e.getMessage());
e.printStackTrace();
}
}
public void update(String att)
{
HasChange=true;
Att=att;
}
}最后是测试模块
public class MvcAndFac {
public static void main(String[] args) {
FacCon Controller=new FacCon();//获取唯一实例
Controller.setMode(1);
Controller.ShowView();
}
}
public class MvcAndFac {
public static void main(String[] args) {
FacCon Controller=new FacCon();//获取唯一实例
Controller.setMode(1);
Controller.ShowView();
}
}
本文详细解析了工厂模式的不同类型,包括简单工厂模式、工厂方法模式及抽象工厂模式,并通过一个MVC架构的实例展示了如何在实际项目中应用工厂方法模式。
2267

被折叠的 条评论
为什么被折叠?



