记住所有设计模式并不容易。这里有一些关于设计模式的故事,可能会有所帮助
创造器
Java设计模式:单例
单例模式是Java中最常用的模式之一。它用于通过防止外部实例化和修改来控制创建的对象数。可以将此概念推广到仅存在一个对象的情况下可以更有效地运行的系统,或者将实例化限制为一定数量的对象的系统,例如:
- 私有构造函数-没有其他类可以实例化新对象。
- 私人参考-无需外部修改。
- 公共静态方法是唯一可以获取对象的地方。
辛格尔顿的故事
这是一个简单的用例。一个国家只能有一位总统。因此,每当需要一位总统时,都应该选出唯一的总统,而不是创建新的总统。该getPresident()方法将确保始终只创建一个总裁。
类图和代码
急切模式:
public class AmericaPresident {
private static final AmericaPresident thePresident = new AmericaPresident();
private AmericaPresident() {}
public static AmericaPresident getPresident() {
return thePresident;
}
}
thePresident声明为final,因此它将始终包含相同的对象引用。
惰性模式:
public class AmericaPresident {
private static AmericaPresident thePresident;
private AmericaPresident() {}
public static AmericaPresident getPresident() {
if (thePresident == null) {
thePresident = new AmericaPresident();
}
return thePresident;
}
}
Java Stand库中使用的Singleton模式
java.lang.Runtime#getRuntime()是Java标准库中的一种常用方法。getRunTime()返回与当前Java应用程序关联的运行时对象。
class Runtime {
private static Runtime currentRuntime = new Runtime();
public static Runtime getRuntime() {
return currentRuntime;
}
private Runtime() {}
//...
}
这是使用的简单示例getRunTime()。它在Windows系统上读取网页。
Process p = Runtime.getRuntime().exec(
"C:/windows/system32/ping.exe [programcreek.com](http://programcreek.com/)");
//get process input stream and put it to buffered reader
BufferedReader input = new BufferedReader(new InputStreamReader(
p.getInputStream()));
String line;
while ((line = input.readLine()) != null) {
System.out.println(line);
}
input.close();
输出:
Pinging [programcreek.com](http://programcreek.com/) [198.71.49.96] with 32 bytes of data:
Reply from 198.71.49.96: bytes=32 time=53ms TTL=47
Reply from 198.71.49.96: bytes=32 time=53ms TTL=47
Reply from 198.71.49.96: bytes=32 time=52ms TTL=47
Reply from 198.71.49.96: bytes=32 time=53ms TTL=47
Ping statistics for 198.71.49.96:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 52ms, Maximum = 53ms, Average = 52ms
单例模式的另一种实现
由于私有构造函数无法防止通过反射实例化,因此Joshua Bloch(有效Java)提出了更好的Singleton实现。如果您不熟悉Enum,这是Oracle的一个很好的例子。
public enum AmericaPresident{
INSTANCE;
public static void doSomething(){
//do something
}
}
Java设计模式:工厂
1.工厂模式的故事
工厂设计模式用于基于不同的参数创建对象。下面的示例是关于在工厂中创建人员的。如果我们要求工厂生个男孩,工厂将生一个男孩。如果我们要一个女孩,工厂将生产一个女孩。根据不同的参数,工厂生产不同的东西。
2.工厂模式类图
3.工厂模式Java代码
interface Human {
public void Talk();
public void Walk();
}
class Boy implements Human{
@Override
public void Talk() {
System.out.println("Boy is talking...");
}
@Override
public void Walk() {
System.out.println("Boy is walking...");
}
}
class Girl implements Human{
@Override
public void Talk() {
System.out.println("Girl is talking...");
}
@Override
public void Walk() {
System.out.println("Girl is walking...");
}
}
public class HumanFactory {
public static Human createHuman(String m){
Human p = null;
if(m.equals("boy")){
p = new Boy();
}else if(m.equals("girl")){
p = new Girl();
}
return p;
}
}
4. Java标准库中使用的工厂设计模式
基于不同的参数,getInstance()返回日历的不同实例。
java.util.Calendar-getInstance()
java.util.Calendar-getInstance(TimeZone zone)
java.util.Calendar-getInstance(Locale aLocale)
java.util.Calendar-getInstance(TimeZone zone,Locale aLocale)
java.text.NumberFormat
-getInstance ()java.text.NumberFormat-getInstance(Locale inLocale)
Java设计模式:抽象工厂
抽象工厂模式为工厂模式添加了另一层抽象。如果将“抽象工厂”与“工厂”进行比较,则很明显添加了新的抽象层。抽象工厂是创建其他工厂的超级工厂。我们可以称其为“工厂的工厂”。
抽象工厂类图
抽象工厂Java代码
interface CPU {
void process();
}
interface CPUFactory {
CPU produceCPU();
}
class AMDFactory implements CPUFactory {
public CPU produceCPU() {
return new AMDCPU();
}
}
class IntelFactory implements CPUFactory {
public CPU produceCPU() {
return new IntelCPU();
}
}
class AMDCPU implements CPU {
public void process() {
System.out.println("AMD is processing...");
}
}
class IntelCPU implements CPU {
public void process() {
System.out.println("Intel is processing...");
}
}
class Computer {
CPU cpu;
public Computer(CPUFactory factory) {
cpu = factory.produceCPU();
cpu.process();
}
}
public class Client {
public static void main(String[] args) {
new Computer(createSpecificFactory());
}
public static CPUFactory createSpecificFactory() {
int sys = 0; // based on specific requirement
if (sys == 0)
return new AMDFactory();
else
return new IntelFactory();
}
}
实际使用示例
实际上,这是现代框架的一个非常重要的概念。这是一个有关此的问题。
Java设计模式:构建器
Builder模式的关键特征在于它涉及逐步构建内容的过程,即,即使每个步骤都不相同,每个产品也会遵循相同的过程。
在下面的示例中,我们可以定义一个名为StarbucksBuilder的饮料构建器,它将构建一个星巴克饮料。StarbucksBuilder有几个步骤来构建Starbucks饮料,例如buildSize()和buildDrink()。最后退还酒水。
1.生成器设计模式类图
2. Builder设计模式Java代码示例
package designpatterns.builder;
// produce to be built
class Starbucks {
private String size;
private String drink;
public void setSize(String size) {
this.size = size;
}
public void setDrink(String drink) {
this.drink = drink;
}
}
//abstract builder
abstract class StarbucksBuilder {
protected Starbucks starbucks;
public Starbucks getStarbucks() {
return starbucks;
}
public void createStarbucks() {
starbucks = new Starbucks();
System.out.println("a drink is created");
}
public abstract void buildSize();
public abstract void buildDrink();
}
// Concrete Builder to build tea
class TeaBuilder extends StarbucksBuilder {
public void buildSize() {
starbucks.setSize("large");
System.out.println("build large size");
}
public void buildDrink() {
starbucks.setDrink("tea");
System.out.println("build tea");
}
}
// Concrete builder to build coffee
class CoffeeBuilder extends StarbucksBuilder {
public void buildSize() {
starbucks.setSize("medium");
System.out.println("build medium size");
}
public void buildDrink() {
starbucks.setDrink("coffee");
System.out.println("build coffee");
}
}
//director to encapsulate the builder
class Waiter {
private StarbucksBuilder starbucksBuilder;
public void setStarbucksBuilder(StarbucksBuilder builder) {
starbucksBuilder = builder;
}
public Starbucks getstarbucksDrink() {
return starbucksBuilder.getStarbucks();
}
public void constructStarbucks() {
starbucksBuilder.createStarbucks();
starbucksBuilder.buildDrink();
starbucksBuilder.buildSize();
}
}
//customer
public class Customer {
public static void main(String[] args) {
Waiter waiter = new Waiter();
StarbucksBuilder coffeeBuilder = new CoffeeBuilder();
//Alternatively you can use tea builder to build a tea
//StarbucksBuilder teaBuilder = new TeaBuilder();
waiter.setStarbucksBuilder(coffeeBuilder);
waiter.constructStarbucks();
//get the drink built
Starbucks drink = waiter.getstarbucksDrink();
}
}
3.实际使用的构建器设计模式
Builder模式已在许多库中使用。但是,这里有一个常见错误。考虑以下StringBuilder示例,它是Java标准库中的类。它是否利用了Builder模式?
StringBuilder strBuilder= new StringBuilder();
strBuilder.append("one");
strBuilder.append("two");
strBuilder.append("three");
String str= strBuilder.toString();
在Java标准库中,StringBuilder扩展了AbstractStringBuilder。
append()方法是该过程的第一步,就像我们的星巴克示例中的步骤一样。toString()方法是另一个方法,它是最后一步。但是,这里的区别在于图片中没有服务员。Waiter类在Builder模式的图片中扮演导演角色。由于没有这种角色,因此它不是构建器模式。
当然,这不是唯一的原因。您可以在开始时与类图进行比较,然后找出另一个原因。
4.建造者和工厂之间的区别
当有很多创建对象的步骤时,将使用构建器模式。当工厂可以在一个方法调用中轻松创建整个对象时,将使用工厂模式。
Java设计模式:原型
当经常创建非常相似的对象时,使用原型设计模式。原型模式将克隆对象并设置更改的功能。这样,消耗的资源更少。
1.原型模式类图
2.原型模式Java示例
package designpatterns.prototype;
//prototype
interface Prototype {
void setSize(int x);
void printSize();
}
// a concrete class
class A implements Prototype, Cloneable {
private int size;
public A(int x) {
this.size = x;
}
@Override
public void setSize(int x) {
this.size = x;
}
@Override
public void printSize() {
System.out.println("Size: " + size);
}
@Override
public A clone() throws CloneNotSupportedException {
return (A) super.clone();
}
}
//when we need a large number of similar objects
public class PrototypeTest {
public static void main(String args[]) throws CloneNotSupportedException {
A a = new A(1);
for (int i = 2; i < 10; i++) {
Prototype temp = a.clone();
temp.setSize(i);
temp.printSize();
}
}
}
3. Java标准库中使用的原型设计模式
java.lang.Object-clone()
网友评论