首页 > Python基础教程 >
-
java教程之Java常见设计模式学习(非原创)(2)
现在我们来分析天气台类,天气台实现了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