VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • java教程之Java常见设计模式学习(非原创)(2)

notifObserver() { for (int i = 0; i < observers.size(); i++) { Observer observer = observers.get(i); observer.getMeteorologicalStationData(getPressure(), getTemperature(), getHumidity()); } } }

现在我们来分析天气台类,天气台实现了Subject,并用集合的形式方便的管理多个客户的接入与离开,在notifObserver中实时的上传天气数据。好的,现在我们看看其他客户的接入:

public class ACompany implements Observer{
    @Override
    public void getMeteorologicalStationData(float pressure,float temperature,float humidity){
        System.out.println("A pressure: "+pressure+",temperature: "+temperature+",humidity: "+humidity);
    }
}
public class BCompany implements Observer{

    @Override
    public void getMeteorologicalStationData(float pressure, float temperature, float humidity) {
        System.out.println("B pressure: "+pressure+",temperature: "+temperature+",humidity: "+humidity);
    }

}

好的我们可以看到无论有多少个公司想要接入,现在只需要实现Observer接口即可。现在我们来测试下:

 
 

看到这里我们已经知道了观察者模式的好处,下面我们看看java内置的观察者:

public class MeteorologicalStation extends Observable {
    private float pressure;
    private float temperature;
    private float humidity;

    public float getPressure() {
        return pressure;
    }

    public float getTemperature() {
        return temperature;
    }

    public float getHumidity() {
        return humidity;
    }

    public void uploadData(float pressure, float temperature, float humidity) {
        this.pressure = pressure;
        this.temperature = temperature;
        this.humidity = humidity;
        WeatherData data=new WeatherData(pressure, temperature, humidity);
        /**
         * setChanged
         * 根据有些特定的需求出现的,设置后唤醒才有效,
         * 例如我们不需要温度改变0.5我们也去唤醒客户,
         * 因此这里我们可以判断后在设置
         * */
        this.setChanged();
        this.notifyObservers(data);
    }

     public class WeatherData{
         public float pressure;
         public float temperature;
         public float humidity;
         public WeatherData(float pressure, float temperature, float humidity) {
            this.pressure = pressure;
            this.temperature = temperature;
            this.humidity = humidity;
        }

    }
}

从代码中可以看到Observable 是一个类 而不是像我们一样的Subject的接口

this.setChanged();
this.notifyObservers(data);

两个一起使用才有效,下面我们看看A,B公司需要怎么做:

public class ACompany implements Observer{

    @Override
    public void update(Observable arg0, Object arg1) {
        WeatherData data=(WeatherData) arg1;
        System.out.println("A pressure: "+data.pressure+",temperature: "+data.temperature+",humidity: "+data.humidity);
    }
}
public class BCompany implements Observer{

    @Override
    public void update(Observable o, Object arg) {
        WeatherData data=(WeatherData) arg;
        System.out.println("B pressure: "+data.pressure+",temperature: "+data.temperature+",humidity: "+data.humidity);
    }
}

A,B公司只要实现系统的Observer接口,和我们刚才的设计是一样的。最后我们在测试一下:

 
 

可以看到和我们之前的效果完全一样

三、工厂模式

项目需求:生产披萨项目,生产披萨需要经过准备,烘烤,剪切,打包 4个步骤,根据客户输入的披萨名字生产对应的披萨。
首先用传统的方式去做:

public abstract class Pizza {
    protected String name;

    public abstract void prepare();
    public void bake()
    {
        System.out.println(name+" baking;");
    }
    public void cut()
    {
        System.out.println(name+" cutting;");
    }
    public void box()
    {
        System.out.println(name+" boxing;");
    }
    public void setname(String name)
    {
        this.name=name;
    }
}
public class PepperPizza extends Pizza{

    @Override
    public void prepare() {
        super.setname("PepperPizza");
        System.out.println("PepperPizza");
    }

}
public class GreekPizza extends Pizza{

    @Override
    public void prepare() {
        super.setname("GreekPizza");
        System.out.println("GreekPizza");
    }

}
public class CheesePizza extends Pizza{

    @Override
    public void prepare() {
        super.setname("CheesePizza");
        System.out.println("CheesePizza");
    }

}
public class OrderPizza {

    OrderPizza(){
        String type=null;
        Pizza pizza=null;
        do {
            type=getType();
            if (type.equals("greek")) {
                pizza=new GreekPizza();
            }else if (type.equals("cheese")) {
                pizza=new CheesePizza();
            }else if (type.equals("pepper")) {
                pizza=new PepperPizza();
            }else{
                break;
            }
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
        } while (true);
    }

    private String getType(){
        String type=null;
        BufferedReader br=null;
        try {
            br=new BufferedReader(new InputStreamReader(System.in));
            System.out.println("input pizza type:");
            type= br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
        return type;
    }
}

代码分析:首先我们考虑到生产披萨的4步骤是一样的,只有名字不一样,所以我们将名字方法抽象出来,友各个披萨类去实现,然后通过OrderPizza 类去模仿工厂生产的过程。
最后我们来测试一下:

public class test {

    public static void main(String[] args) {
        OrderPizza order1=new OrderPizza();
    }

}
 

然后现在又研究出了几个新的披萨品种,需要加入到系统中,那么如果继续在传统的方式中修改,我们只需要增加新品种披萨类,然后修改 OrderPizza 中的判断语句。

我们现在用简单工厂模式下试一下:
简单工厂类中各种披萨类还是一样,修改的是OrderPizza:

public class OrderPizza {

    OrderPizza(SimpleFactoryPizza factory){
        String type=null;
        Pizza pizza=null;
        do {
            type=getType();
            pizza=factory.createPizza(type);
            if (pizza!=null) {
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            }else{
                break;
            }
        } while (true);
    }

    private String getType(){
        String type=null;
        BufferedReader br=null;
        try {
            br=new BufferedReader(new InputStreamReader(System.in));
            System.out.println("input pizza type:");
            type= br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
        return type;
    }
}
public class SimpleFactoryPizza {
    public Pizza createPizza(String type){
        Pizza pizza=null;
        if (type.equals("greek")) {
            pizza=new GreekPizza();
        }else if (type.equals("cheese")) {
            pizza=new CheesePizza();
        }else if (type.equals("pepper")) {
            pizza=new PepperPizza();
        }else if (type.equals("beef")) {
            pizza=new BeefPizza();
        }
        return pizza;
    }
}

虽然看似代码是一样的,但是我们已经将变化的代码抽取出来了,在OrderPizza中我们无需再次修改,此时我们已经将变化的和不变化的隔离开来了
然后现在我们需要在纽约,伦敦生产披萨,且各地生成的披萨都各有差异,那么我们现在使用工厂方法模式试试:

public class LDCheesePizza extends Pizza{

    @Override
    public void prepare() {
        super.setname("LDCheesePizza");
        System.out.println("LDCheesePizza");
    }

}
public class LDGreekPizza extends Pizza{

    @Override
    public void prepare() {
        super.setname("LDGreekPizza");
        System.out.println("LDGreekPizza");
    }

}
public class LDPepperPizza extends Pizza{

    @Override
    public void prepare() {
        super.setname("LDPepperPizza");
        System.out.println("LDPepperPizza");
    }

}

纽约的也一样,我们再来看看OrderPizza

public abstract class OrderPizza {

    public abstract Pizza createPizza(String type);
    public OrderPizza(){
        String type=null;
        Pizza pizza=null;
        do {
            type=getType();
            pizza=createPizza(type);
            if (pizza!=null) {
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            }else{
                break;
            }
        } while (true);
    }

    private String getType(){
        String type=null;
        BufferedReader br=null;
        try {
            br=new BufferedReader(new InputStreamReader(System.in));
            System.out.println("input pizza type:");
            type= br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
        return type;
    }
}

这里因为工厂是多样化的,所以这里我们将工厂抽象,然后看具体实现:

public class NewYorkOrderPizza extends OrderPizza {

    @Override
    public Pizza createPizza(String type) {
        Pizza pizza=null;
        if (type.equals("greek")) {
            pizza=new LDGreekPizza();
        }else if (type.equals("cheese")) {
            pizza=new LDCheesePizza();
        }else if (type.equals("pepper")) {
            pizza=new LDPepperPizza();
        }
        return pizza;
    }

}
public class LondonOrderPizza extends OrderPizza {

    @Override
    public Pizza createPizza(String type) {
        Pizza pizza=null;
        if (type.equals("greek")) {
            pizza=new NYGreekPizza();
        }else if (type.equals("cheese")) {
            pizza=new NYCheesePizza();
        }else if