设计模式剖析系列之工厂方法模式

By heiry on 2019-08-05 [ in 技术 ]

工厂方法模式

静态工厂方法只有一个工厂类,且如果要增加产品,则需要修改工厂类代码,违背了开闭原则。工厂方法模式则将工厂类颗粒化,为每一种产品单独设立一个工厂类。

工厂方法模式UML图

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package staticfactory;
public interface Computer {
public abstract void cal();
}
package staticfactory; public interface Computer { public abstract void cal(); }
package staticfactory;

public interface Computer {
  public abstract void cal();

}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package net.mosang.factory;
public class Mac implements Computer {
@Override
public void cal() {
System.out.println("苹果电脑启动。。。。");
}
}
package net.mosang.factory; public class Mac implements Computer { @Override public void cal() { System.out.println("苹果电脑启动。。。。"); } }
package net.mosang.factory;
public class Mac implements Computer {

  @Override
  public void cal() {
    System.out.println("苹果电脑启动。。。。");
  }
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package net.mosang.factory;
public class HP implements Computer {
@Override
public void cal() {
System.out.println("惠普电脑启动。。。。");
}
}
package net.mosang.factory; public class HP implements Computer { @Override public void cal() { System.out.println("惠普电脑启动。。。。"); } }
package net.mosang.factory;

public class HP implements Computer {

  @Override
  public void cal() {
    System.out.println("惠普电脑启动。。。。");

  }
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package net.mosang.factory;
public interface ComputerFactoryBasic {
public abstract Computer CreateComputer();
}
package net.mosang.factory; public interface ComputerFactoryBasic { public abstract Computer CreateComputer(); }
package net.mosang.factory;

public interface ComputerFactoryBasic {
  public abstract Computer CreateComputer();
  
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package net.mosang.factory;
public class MacFactory implements ComputerFactoryBasic {
@Override
public Computer CreateComputer() {
return new Mac();
}
}
package net.mosang.factory; public class MacFactory implements ComputerFactoryBasic { @Override public Computer CreateComputer() { return new Mac(); } }
package net.mosang.factory;

public class MacFactory implements ComputerFactoryBasic {

  @Override
  public Computer CreateComputer() {
    return new Mac();
  }

}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package net.mosang.factory;
public class HPFactory implements ComputerFactoryBasic {
@Override
public Computer CreateComputer() {
return new HP();
}
}
package net.mosang.factory; public class HPFactory implements ComputerFactoryBasic { @Override public Computer CreateComputer() { return new HP(); } }
package net.mosang.factory;

public class HPFactory implements ComputerFactoryBasic {

  @Override
  public Computer CreateComputer() {
    return new HP();
  }

}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package net.mosang.factory;
public class Client {
public static void main(String[] args) {
Computer computer = new MacFactory().CreateComputer();
Computer computer2 = new HPFactory().CreateComputer();
computer.cal();
computer2.cal();
}
}
package net.mosang.factory; public class Client { public static void main(String[] args) { Computer computer = new MacFactory().CreateComputer(); Computer computer2 = new HPFactory().CreateComputer(); computer.cal(); computer2.cal(); } }
package net.mosang.factory;

public class Client {

  public static void main(String[] args) {		
    Computer computer = new MacFactory().CreateComputer();
    Computer computer2 = new HPFactory().CreateComputer();
    computer.cal();
    computer2.cal();
    
  }
}

输出结果

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
苹果电脑启动。。。。
惠普电脑启动。。。。
苹果电脑启动。。。。 惠普电脑启动。。。。
苹果电脑启动。。。。
惠普电脑启动。。。。

 

>> 阅读全文  >>

设计模式剖析系列之静态工厂方法

By heiry on 2019-08-05 [ in 技术 ]

作用:在Think in java 系列书籍以及网上大量的文章都写了其各种各样的好处,我认为言过其实,我们用静态工厂方法,主要原因在于可以根据逻辑需求返回实例对象。可以方便实现工厂模式、单例模式。其它如,有语义方法名、返回其返回类型的任何子类型的对象,方便创建参数化类型实例等等都是无关痛痒的东西。

实现:

将创建实例封装在一个工厂类的静态方法中,静态方法不同的参数返回不同的实例。

示例:

如下所示,电脑工厂类,通过提供静态方法getComputer(String Brand)生产不同品牌的电脑(返回Computer实例对象),客户端只需要调用静态工厂方法传入不同参数即可获得目标对象。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package staticfactory;
public interface Computer {
public abstract void cal();
}
package staticfactory; public interface Computer { public abstract void cal(); }
package staticfactory;
public interface Computer {
  public abstract void cal();
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package staticfactory;
public class Mac implements Computer {
@Overrid
public void cal() {
System.out.println("苹果电脑启动。。。。");
}
}
package staticfactory; public class Mac implements Computer { @Overrid public void cal() { System.out.println("苹果电脑启动。。。。"); } }
package staticfactory;
public class Mac implements Computer {
  @Overrid
  public void cal() {
    System.out.println("苹果电脑启动。。。。");
  }
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package staticfactory;
public class HP implements Computer {
@Override
public void cal() {
System.out.println("惠普电脑启动。。。。");
}
}
package staticfactory; public class HP implements Computer { @Override public void cal() { System.out.println("惠普电脑启动。。。。"); } }
package staticfactory;
public class HP implements Computer {
  @Override
  public void cal() {
    System.out.println("惠普电脑启动。。。。");

  }
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package staticfactory;
public class ComputerFactory {
public static Computer getComputer(String computerBrand) {
switch (computerBrand) {
case "Mac":
return new Mac();
case "HP":
return new HP();
default:
return null;
}
}
}
package staticfactory; public class ComputerFactory { public static Computer getComputer(String computerBrand) { switch (computerBrand) { case "Mac": return new Mac(); case "HP": return new HP(); default: return null; } } }
package staticfactory;
public class ComputerFactory {	
  public static Computer getComputer(String computerBrand) {
    switch (computerBrand) {
    case "Mac":
      return new Mac();
    case "HP":
      return new HP();
    default:
      return null;
    }
  }
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package staticfactory;
public class Client {
public static void main(String[] args) {
Computer computer = ComputerFactory.getComputer("Mac");
Computer computer2 = ComputerFactory.getComputer("HP");
computer.cal();
computer2.cal();
}
}
package staticfactory; public class Client { public static void main(String[] args) { Computer computer = ComputerFactory.getComputer("Mac"); Computer computer2 = ComputerFactory.getComputer("HP"); computer.cal(); computer2.cal(); } }
package staticfactory;

public class Client {
  public static void main(String[] args) {
    Computer computer = ComputerFactory.getComputer("Mac");
    Computer computer2 = ComputerFactory.getComputer("HP");
    computer.cal();
    computer2.cal();
  }
}

运行结果:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
苹果电脑启动。。。。
惠普电脑启动。。。。
苹果电脑启动。。。。 惠普电脑启动。。。。
苹果电脑启动。。。。
惠普电脑启动。。。。

 

>> 阅读全文  >>

设计模式剖析系列之面向对象设计原则

By heiry on 2019-08-04 [ in 技术 ]

一.开闭原则

实现方式:

1. 遵循“抽象约束、封装变化”原则,通过接口或者抽象类为实体定义一个相对稳定的抽象层,而将相同的可变因素封装在相同的具体实现类中。

2.参数类型、引用对象尽量使用接口或者抽象类,而不是实现类。

3.缩小功能颗粒度。功能粒度越小,被复用的可能性就越大,重复利用可能性就越高。

二. 里氏替换原则

简单地说,把父类都替换成它的子类,程序的行为没有变化。只要出现父类的地方,均可用子类替换,而且对整体实现并没有任何影响,提高代码的复用性。

实现方式:

子类继承父类时,除添加新的方法完成新增功能外,尽量不要重写父类的方法。

三. 依赖倒置原则

——高层模块不应该依赖低层模块,两者都应该依赖其抽象

——抽象不应该依赖细节

——细节应该依赖抽象

实现方式:

1.每个类尽量提供接口或抽象类,或者两者都具备。

2.变量的声明类型尽量是接口或者是抽象,模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的。

3.任何类都不应该从具体类派生。

4.尽量不要重写基类已经写好的方法(符合里氏替换原则)。

>> 阅读全文  >>

设计模式剖析系列之UML类关系

By heiry on 2019-08-04 [ in 技术 ]

设计模式实质上并没有新的东西,只是一种思想体现,来来去去都是在围绕继承、多态、静态之间做文章。很多人学设计模式很吃力,被其中类之间复杂的引用关系绕晕,我认为掌握设计模式最重要的一步就是把常见类之间关系梳理出来,而UML早已经帮我们做了,拿来理顺即可。

一. 依赖关系Dependency

依赖关系是一种临时关系、使用的弱关系,是耦合度最低的一种关系。

代码表现:一个类的方法通过局部变量、方法的参数或者对静态方法的调用来访问另一个类(被依赖类)。下例中,猎人(Hunter)和枪(Gun)之间是一种使用关系,猎人使用枪进行射击,枪Gun作为一个参数出现在猎人shoot方法中(Hunter类中猎杀动作shoot()调用了Gun实例的开火fire()方法):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package com.mosang.umlmodule;
public class Hunter {
private String name;
public void shoot(Gun g) {
g.fire();
}
}
package com.mosang.umlmodule; public class Hunter { private String name; public void shoot(Gun g) { g.fire(); } }
package com.mosang.umlmodule;

public class Hunter {
  private String name;
  public void shoot(Gun g) {
    g.fire();
  }

}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package com.mosang.umlmodule;
public class Gun {
private String brand;
public void fire() {
System.out.println("shoot.....");
}
}
package com.mosang.umlmodule; public class Gun { private String brand; public void fire() { System.out.println("shoot....."); } }
package com.mosang.umlmodule;

public class Gun {
  private String brand;
  public void fire() {
    System.out.println("shoot.....");
  }
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package com.mosang.umlmodule;
public class Client {
public static void main(String[] args) {
Hunter hunter = new Hunter();
hunter.shoot(new Gun());
}
}
package com.mosang.umlmodule; public class Client { public static void main(String[] args) { Hunter hunter = new Hunter(); hunter.shoot(new Gun()); } }
package com.mosang.umlmodule;

public class Client {

  public static void main(String[] args) {
    Hunter hunter = new Hunter();
    hunter.shoot(new Gun());

  }
}

UML图示:

二. 关联关系Association

关联关系是对象之间的一种引用关系,用于表示一类对象与另一类对象之间的联系,如学生与老师、公司与员工、宠物与主人等等,存在一对一,一对多,多对多等关系。

代码表现:一个类的对象作为另一个类的成员变量。下例中学生与老师是一种多对多的关系(一个学生同时有多个老师教,一个老师也同时教多个学生),Student类作为成员变量出现在Teacher类中,Teacher类也作为成员变量出现在Student类中:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package com.mosang.umlmodule;
import java.util.List;
public class Student {
private String name;
private List<Teacher> teachers;
public void study() {
}
}
package com.mosang.umlmodule; import java.util.List; public class Student { private String name; private List<Teacher> teachers; public void study() { } }
package com.mosang.umlmodule;
import java.util.List;

public class Student {
  private String name;
  private List<Teacher> teachers;
  public void study() {
    
  }
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package com.mosang.umlmodule;
import java.util.List;
public class Teacher {
private String name;
private List<Student> students;
public void teach() {
}
}
package com.mosang.umlmodule; import java.util.List; public class Teacher { private String name; private List<Student> students; public void teach() { } }
package com.mosang.umlmodule;
import java.util.List;

public class Teacher {
  private String name;
  private List<Student> students;
  public void teach() {
    
  }
}

UML图示:

【双向的关联可以用带两个箭头或者没有箭头的实线来表示,单向的关联用带一个箭头的实线来表示,箭头从使用类指向被关联的类。也可以在关联线的两端标注角色名,代表两种不同的角色。】 (更多…)

>> 阅读全文  >>

静态隐藏与覆盖的不同

By heiry on 2019-08-04 [ in 技术 ]

java中,静态方法属于类,直接使用”类名.静态方法”方式访问,也可以通过”实例.方法”访问,后者一般不推荐,但是也是合法的:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package com.mosang.staticInheri;
public class Fu {
public String a="fu";
public void ordinaryMethod() {
System.out.println("Fu ordinaryMethod");
}
public static void staticMethod() {
System.out.println("Fu static method");
}
}
package com.mosang.staticInheri; public class Fu { public String a="fu"; public void ordinaryMethod() { System.out.println("Fu ordinaryMethod"); } public static void staticMethod() { System.out.println("Fu static method"); } }
package com.mosang.staticInheri;

public class Fu {
  public String a="fu";
  public void ordinaryMethod() {
    System.out.println("Fu ordinaryMethod");
    
  }
  public static void staticMethod() {
    System.out.println("Fu static method");
  }

}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package com.mosang.staticInheri;
public class Demo {
public static void main(String[] args) {
Fu f=new Fu();
f.staticMethod();//使用实例方式访问
Fu.staticMethod();//使用类名直接访问
}
}
package com.mosang.staticInheri; public class Demo { public static void main(String[] args) { Fu f=new Fu(); f.staticMethod();//使用实例方式访问 Fu.staticMethod();//使用类名直接访问 } }
package com.mosang.staticInheri;

public class Demo {
  public static void main(String[] args) {
    Fu f=new Fu();
    f.staticMethod();//使用实例方式访问
    Fu.staticMethod();//使用类名直接访问
  }

}

输出如下:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Fu static method
Fu static method
Fu static method Fu static method
Fu static method
Fu static method

需要注意的是,在存在静态方法情况下的继承,静态方法不能被子类覆盖,即使子类有与父类相同的静态方法(同覆盖规则),也不是覆盖重写,如有Zi类继承如下:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package com.mosang.staticInheri;
public class Zi extends Fu{
public String a="zi";
public void ordinaryMethod() {
System.out.println("Zi ordinaryMethod"); //实例方法,覆盖重写
}
public static void staticMethod() {
System.out.println("Zi static method"); //与父类相同的静态方法(方法名、返回值、参数均相同)
}
}
package com.mosang.staticInheri; public class Zi extends Fu{ public String a="zi"; public void ordinaryMethod() { System.out.println("Zi ordinaryMethod"); //实例方法,覆盖重写 } public static void staticMethod() { System.out.println("Zi static method"); //与父类相同的静态方法(方法名、返回值、参数均相同) } }
package com.mosang.staticInheri;

public class Zi extends Fu{
  public String a="zi";
  public void ordinaryMethod() {
    System.out.println("Zi ordinaryMethod"); //实例方法,覆盖重写
    
  }
  public static void staticMethod() {
    System.out.println("Zi static method"); //与父类相同的静态方法(方法名、返回值、参数均相同)
  }

}

通过两种方式创建子类实例:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package com.mosang.staticInheri;
public class Demo {
public static void main(String[] args) {
Fu f1=new Zi();//多态方式创建对象
Zi f2=new Zi();//普通方式创建对象
f1.ordinaryMethod(); //输出Zi ordinaryMethod
f1.staticMethod();//输出Fu static method
f2.ordinaryMethod();//Zi ordinaryMethod
f2.staticMethod();//Zi static method
}
}
package com.mosang.staticInheri; public class Demo { public static void main(String[] args) { Fu f1=new Zi();//多态方式创建对象 Zi f2=new Zi();//普通方式创建对象 f1.ordinaryMethod(); //输出Zi ordinaryMethod f1.staticMethod();//输出Fu static method f2.ordinaryMethod();//Zi ordinaryMethod f2.staticMethod();//Zi static method } }
package com.mosang.staticInheri;

public class Demo {
  public static void main(String[] args) {
    Fu f1=new Zi();//多态方式创建对象
    Zi f2=new Zi();//普通方式创建对象
    f1.ordinaryMethod(); //输出Zi ordinaryMethod
    f1.staticMethod();//输出Fu static method
    f2.ordinaryMethod();//Zi ordinaryMethod
    f2.staticMethod();//Zi static method
  }

}

输出结果

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Zi ordinaryMethod
Fu static method
Zi ordinaryMethod
Zi static method
Zi ordinaryMethod Fu static method Zi ordinaryMethod Zi static method
Zi ordinaryMethod
Fu static method
Zi ordinaryMethod
Zi static method

从上输出结果可看到,父类的静态方法并不能被覆盖,只是被隐藏。

同样,静态成员变量也是一样的道理。出现相同静态字段时父类字段不会将子类字段覆盖,而只是将其“隐藏”。

>> 阅读全文  >>

无题

By heiry on 2019-07-31 [ in 生活, 随写 ]

>> 阅读全文  >>

智慧

By heiry on 2019-07-29 [ in 生活, 管理, 随写 ]

大学时,学校有个名家讲坛,有很多名人来演讲,包括袁隆平、王石、白岩松、唐骏、王蒙、余秋雨、陈鲁豫,俞敏洪、李开复。。。等等,其中特别多的是央视名嘴,和很多懵懂的大学新生一样,我很热衷于听这样的讲座,想着从中吸取到这些成功人士的思想智慧。然而,更多留下的印象是他们在讲那些所谓光辉往事,多年后想起来,这些花去了大量时间的名人讲座对我毫无帮助,大脑中对这些讲座的印象已经趋近于零,有很多后来还因为人设的坍塌而起了反效果。相反,有一堂看似不起眼的财务管理会计实操课,对我印象深刻。那次老师邀请了一家证券公司的专业财税人员来给我们讲解,讲课人干净利落的职业着装,口齿清晰的表达,逻辑清晰且优美的PPT,娴熟的软件操作,给我留下了极深的印象,第一次觉得财务课程还可以不沉闷,还可以有如此专业深度,这么多年过去,那次课我依然记忆犹新。

我们常常在网上、在节目访谈中,在演讲上,在他人写的书中,看到或听到各种诗般的旅行体验,传奇的创业故事,艰苦奋斗的历程,力挽狂澜的励志片段、远见卓识的前瞻思维、开山劈地般的气魄,这些让你的神经猛然得到刺激,鸡汤效应让人一时间兴奋起来。然而当你走近或去经历的时候,才发现所有这些,都与你想的相去甚远。几乎每个给别人讲故事的人,都不由自主地往其中添加了或多或少的兴奋剂,有的甚至只剩下兴奋剂了。 (更多…)

>> 阅读全文  >>


© 2009-2024 MOSANG.NET DESIGNED BY HEIRY