MVC框架下工厂方法模式挑奇偶(视图与控制台两种view模式)

来源:互联网 发布:java class 重命名 编辑:程序博客网 时间:2024/06/07 12:56

一.何为工厂模式

工厂模式可以分为三类: 

1)简单工厂模式(Simple Factory) 
2)工厂方法模式(Factory Method) 
3)抽象工厂模式(Abstract Factory) 

 这三种模式从上到下逐步抽象,并且更具一般性。 
        GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。

        将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。 

区别 

工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。   
一个抽象工厂类,可以派生出多个具体工厂类。   
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。   
一个抽象工厂类,可以派生出多个具体工厂类。   
每个具体工厂类可以创建多个具体产品类的实例。   
区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。   
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
两者皆可。 

(以上转自http://blog.csdn.net/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);elseNUM=efac.CreateNum(num,VIEW2);}else{if(mode==1)NUM=ofac.CreateNum(num,VIEW1);elseNUM=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.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();}}


四.运行结果

视图模式


控制台

五.总结

首先是要在MVC架构下和工厂模式相结合,然后主要的就是分辨几种工厂模式的差异,通过看一些资深猿的博客弄明白了其中的差别,后面就是代码的实现了。最后就是MVC架构的设计,关于对MVC的理解笔者会在后面的博客再探讨。比较粗糙,如果有什么好的建议与发现什么错误的地方,请在评论区留言谢谢。

0 0
原创粉丝点击