现在的位置: 首页 > 综合 > 正文

学习设计模式之结合简单工厂,策略,装饰的计算器

2013年08月05日 ⁄ 综合 ⁄ 共 6635字 ⁄ 字号 评论关闭

 

今天再回来看一遍的时候,各种痛苦,还是把类的关系,结构梳理一下比较好。。

 

继承关系:DataOperator 实现OperatorMethord接口,继承出加法类和减法类,以及两种装饰类

 

程序运行过程:在UI界面上获取数据,并实例化一个业务类caculator,通过调用业务类的

 

统一的函数getResult获取结果,业务类则自行实例化工厂,并让工厂判断实例化哪一个

 

具体工厂加法或减法,并返回结果。   要加装饰则需在业务类里修改,更换工厂提供的

 

统一返回结果的函数(换成getDecoratedCaculator)获取装饰后的结果。

 

DataOperator.class

package Operation;

/**
 * 该类为所有数据及具体计算的基类,提供数据,并实现计算接口,附带装饰函数
 * @author LEN
 *
 */
public abstract class DataOperator implements OperatorMethord
{
 protected DataOperator  component;
 //protected DataOperator foreComponent,nowComponent;
 protected int numberA = 0;
 protected int numberB = 0;
 
 public DataOperator()
 {
  component = this;
 }
 
 //装饰的本意便是在完成原来功能的基础上添加新功能,因此要保存原类
 /**
  * 保存前一个类
  */
 public void Decorate(DataOperator component)
 {
   this.component = component;
   
 }
 
 /**
  * 设置数据
  */
 public void SetNum(int NumA, int NumB)
 {
  // TODO Auto-generated method stub
  numberA = NumA;
  numberB = NumB;
 }
 
 /**
  *父类的getResult,为虚的,子类必须复写该方法

  */
 public abstract  int getResult()
 }

 

 

OperatorMethord.class

package Operation;

public interface OperatorMethord
{
 
 
 public void SetNum(int NumA,int NumB);
 
 public int getResult();
  
}

 

 

 

OrpFactory.class

package Operation;

public class OprFactory
{
   public OprFactory()
   {
   
   }
   /**
    * 该方法为工厂中获取计算方法并得到结果的函数
    * 可统一调用,判断在这里实现
    * @author LEN
    * @param opr
    * @param numa
    * @param numb
    * @return
    */
   public int getCaculator(String opr,int numa,int numb)
   {//通过利用简单工厂模式使得判断移到了工厂中
 //通过对同一父类实例化为不同对象,再调用相同方法实现策略模式
    if(opr.equals("+"))
    {
     DataOperator op = new AddOperator();
     op.SetNum(numa,numb);
     return op.getResult();
    
    }
    if(opr.equals("-"))
    {
     DataOperator op = new MinusOperator();
     op.SetNum(numa,numb);
     return op.getResult();
    }
    return 0;
   
   
    }
 
  
  
   /**
    * 该方法为工厂中获取计算方法并得到结果的函数,并附加装饰
    *
    * @author LEN
    * @param opr
    * @param numa
    * @param numb
    * @return
    */
   public int getDecoratedCaculator(String opr,int numa,int numb)
   {
   
   
    //装饰之前先赋好变量值装饰函数的调用顺序也要注意(第2出),
    if(opr.equals("+"))
    {
     DataOperator op = new AddOperator();
     DecorateWithZero edop1 = new DecorateWithZero();
     DecoreteWithOne edop2 = new DecoreteWithOne();
    
     op.SetNum(numa,numb);//(1)
     edop1.Decorate(op);//(2)
     edop2.Decorate(edop1);
     //System.out.println("I'm decorating");
    
     return edop2.getResult();
    
    }
    if(opr.equals("-"))
    {
     DataOperator op = new MinusOperator();
     DecorateWithZero edop1 = new DecorateWithZero();
     DecoreteWithOne edop2 = new DecoreteWithOne();
     op.SetNum(numa,numb);
     edop1.Decorate(op);
     edop2.Decorate(edop1);

     //System.out.println("I'm decorating");
    
     return edop2.getResult();
    
    }
    return 0;
   }
}

 

 

AddOperation.class

package Operation;

public class AddOperator extends DataOperator
{
 
 /**
  * 复写具体方法便可完成
  */
 public int getResult()
 {
  // TODO Auto-generated method stub
  System.out.println("not decoreted yet!!!!!!");
  return numberA+numberB;
 }
}

 

MinusOperator.class

package Operation;

public class MinusOperator extends DataOperator
{
 /**
  * 复写具体方法便可完成
  */
 public int getResult()
 {
  // TODO Auto-generated method stub
  return numberA-numberB;
 }
}

 

 

Caculator.class

package Business;

import Operation.OprFactory;

/**
 * 策略模式中的业务类
 * @return
 * @author LEN
 */
public class Caculator
{
 private int firNum = 0;
 private int secNum = 0;
 private int thrNum = 0;
 private String op = null;
 public Caculator(String opr,int fNum,int sNum)
 {
  firNum = fNum;
  secNum = sNum;
  op = opr;
  
 }
 /**
  * 策略模式中的业务类中的统一调用接口
  * @return
  * @author LEN
  */
 public int getResult()
 {
  OprFactory Of = new OprFactory();
  if(op!=null)
  //return Of.getCaculator(op,firNum,secNum);
   
  //实现装饰模式只能在工厂里实行了,与书中不太一样
   return Of.getDecoratedCaculator(op,firNum,secNum);
  
  else return 0;
 }
}

 

 

DecorateWithZero.class

package Operation;

public class DecorateWithZero extends DataOperator
{
 //此方法不能被调用
 /*@Override
 public int getResult()
 {
  // TODO Auto-generated method stub
  System.out.println("Decoreted!!!!!");//实践证明有super在场该函数就不会被调用
  int temp = super.getResult();
  return temp*10;
 }*/
 
 /**
  * 先调用被装饰前的该方法,完成装饰之后返回
  *
  * @author LEN
  */
 @Override
 public int getResult()
 {
  // TODO Auto-generated method stub
  //本来可以像书中一样直接调用父类的方法,但由于要对该类的成员变量进行操作只能用component.getResult,而不能用super(书中为base)
  return decoreteWithZero(component.getResult());
 }
 
 /**
  * 具体装饰方法
  * @param i
  * @return
  * @author LEN
  */
 protected int decoreteWithZero(int i)
 {
  
  return i*10;
 }
}

 

OperationView.class

package UI;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

import Business.Caculator;
import Operation.OprFactory;

import java.io.*;
public class OperationView implements ActionListener{
 private JFrame jf ;
 private JLabel l1,l2,l3 ;
 private JTextField tf1 ;
 private JTextField tf2;
 private JTextField tf3;
 private JPanel northPanel,centerPanel ;
 private JButton b1,b2 ;
 private File file = new File("c:/login.swing");

 public OperationView() {
  jf = new JFrame("My First WindowTest") ;
  northPanel = new JPanel(new GridLayout(4,4,10,10)) ;
  l1 = new JLabel("数字一") ;
  tf1 = new JTextField() ;
  l2 = new JLabel("数字二") ;
  //tf2 = new JPasswordField() ;
  tf2 = new JTextField();
  l3 = new JLabel("运算符号");
  tf3 = new JTextField();
  
  northPanel.add(l1);
  northPanel.add(tf1);
  northPanel.add(l2);
  northPanel.add(tf2);
  northPanel.add(l3);
  northPanel.add(tf3);
  
  
  centerPanel = new JPanel();
  b1 = new JButton("caculate");
  b2 = new JButton("exit");
  centerPanel.add(b1);
  centerPanel.add(b2);
  
  b1.addActionListener(this);
  b2.addActionListener(this);
  
  jf.add(northPanel);
  jf.add(centerPanel,"South");
  jf.setSize(300,260);
  
  Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
  jf.setLocation(size.width / 2 - jf.getWidth() / 2, size.height / 2 - jf.getHeight() / 2);
  
  jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  jf.setVisible(true);
 }

 @Override
 public void actionPerformed(ActionEvent e)
 {
  // TODO Auto-generated method stub
  if(e.getSource().equals(b1)) {
   
   String firstNum = tf1.getText() ;
   //= String.valueOf(tf2.getPassWord())
   String secondNum = tf2.getText();
   //BufferedReader br = null ;
   String Opr = tf3.getText();
   
   int firNum = Integer.parseInt(firstNum);
   int secNum = Integer.parseInt(secondNum);
   
   Caculator business = new Caculator(Opr,firNum,secNum);
   
   
   int result = business.getResult();
   
   String resultstr = String.valueOf(result);
   l3.setText("结果为");
   tf3.setText(resultstr);
   /*try {
    
    FileReader fr = new FileReader(file);
    br = new BufferedReader(fr);
    //String line = "",str = "" ;
    while((line = br.readLine()) != null) {
     str += line ;
    }
    String[] users = str.split("&&");
    for(String user : users) {
     String[] userInfo = user.split("##");
     if(userInfo[0].equals(username) && userInfo[1].equals(password)) {
      JOptionPane.showMessageDialog(null, "登录成功!") ;
      return ;
     }
    }
    JOptionPane.showMessageDialog(null, "用户名或密码错误!") ;
    return ;
    
   } catch (FileNotFoundException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
   
   
    
   }catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
   }*/
  } else {
   System.exit(0);
  }
 }

}

 

 

抱歉!评论已关闭.