注:该笔记整理自清华大学耿祥义教授的java模式课件
什么是设计模式?
每一个设计模式描述一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样,你就能一次一次地使用该方案而不必做重复劳动。
学习设计模式的重要性
学习设计模式不仅可以使我们使用好这些成功的模式,更重要的是可以使我们更加深刻地理解面向对象的设计思想,非常有利于我们更好地使用面向对象语言解决设计中的问题。
面向对象的几个基本原则
(1) 面向抽象的原则
设计一个类时,不该让该类面向具体的类,而是面向抽象类或接口。
(2) 开-闭原则
设计应该对扩展开放,对修改关闭。
如果您的设计遵守了“开-闭原则”,那么这个设计一定是易维护的,因为在设计中增加新的模块时,不必去修改设计中的核心模块。
(3) 高内聚-低耦合原则
如果类中的方法是一组相关的行为,则该类是高内聚的,反之称为低内聚的。
所谓低耦合就是尽量不要让一个类含有太多的其他类的实例的引用,以避免修改系统的其中一部分会影响到其他部分。
---------------------------------------------------------------------------------------------------------------------------------------------------------------
工厂方法模式(别名:虚拟构造)
定义一个用于创建对象的接口,让子类决定实例化哪一个类。FactoryMethod使一个类的实例化延迟到其子类。
Factory MethodPattern(Another Name: Virtual Constructor)
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
一.概述
当系统准备为用户提供某个类的子类的实例,又不想让用户代码和该子类形成耦合时,就可以使用工厂方法模式来设计系统。工厂方法模式的关键是在一个接口或抽象类中定义一个抽象方法,该方法返回某个类的子类的实例,该抽象类或接口让其子类或实现该接口的类通过重写这个抽象方法返回某个子类的实例。
二.工厂方法模式的结构
(1)模式的结构中包括四种角色
抽象产品(Product)
具体产品(ConcreteProduct)
构造者(Creator)
具体构造者(ConcreteCreator)
(2)模式的UML类图
三.工厂方法模式的使用:一个实例
假设有三个笔芯,分别是红笔芯、蓝笔芯和黑笔芯。用户希望通过圆珠笔来明确笔芯颜色。
1.抽象产品(Product) : PenCore.java
public abstract class PenCore{
String color;
public abstract void writeWord( String s);
}
2.具体产品(ConcreteProduct)_1 :RedPenCore.java
public class RedPenCore extends PenCore{
RedPenCore(){
color="红色";
}
public void writeWord(String s){
System.out.println("写出"+color+"的字:"+s);
}
}
具体产品(ConcreteProduct)_2 : BluePenCore.java
public class BluePenCore extendsPenCore{
BluePenCore(){
color="蓝色";
}
public void writeWord(String s){
System.out.println("写出"+color+"的字:"+s);
}
}
具体产品(ConcreteProduct)_3: BlackPenCore.java
public class BlackPenCore extendsPenCore{
BlackPenCore(){
color="黑色";
}
public void writeWord(String s){
System.out.println("写出"+color+"的字:"+s);
}
}
3.构造者(Creator):BallPen.java
public abstract class BallPen{
BallPen(){
System.out.println("生产了一只装有"+getPenCore().color+"笔芯的圆珠笔");
}
public abstract PenCore getPenCore(); //工厂方法
}
4.具体构造者(ConcreteCreator):
RedBallPen.java
public class RedBallPen extendsBallPen{
public PenCore getPenCore(){
return new RedPenCore();
}
}
BlueBallPen.java
public class BlueBallPen extendsBallPen{
public PenCore getPenCore(){
return new BluePenCore();
}
}
BlackBallPen.java
public class BlackBallPen extendsBallPen{
public PenCore getPenCore(){
return new BlackPenCore();
}
}
5.应用 Application.java
public class Application {
/**
* @param args
*/
publicstatic void main(String[] args) {
//TODO Auto-generated method stub
PenCore penCore;
BallPen ballPen=new BlueBallPen();
penCore=ballPen.getPenCore();
penCore.writeWord("你好,很高兴见到你。");
ballPen=new RedBallPen();
penCore=ballPen.getPenCore();
penCore.writeWord("How areyou?");
ballPen=new BlackBallPen();
penCore= ballPen.getPenCore();
penCore.writeWord("Hi,nice to meetyou.");
}
}
输出结果:
生产了一只装有蓝色笔芯的圆珠笔
写出蓝色的字:你好,很高兴见到你。
生产了一只装有红色笔芯的圆珠笔
写出红色的字:Howare you?
生产了一只装有黑色笔芯的圆珠笔
写出黑色的字:Hi,niceto meet you.
四.工厂方法模式的优点
1. 使用工厂方法可以让用户的代码和某个特定类的子类的代码解耦。
2. 工厂方法使用户不必知道它所使用的对象是怎样被创建的,只需知道该对象有哪些方法即可。
五.一个实例
创建药品对象:系统设计了一个抽象类Drug,该抽象类特别规定了所创建的药品必须给出药品的成分及其含量。Drug目前有两个子类:Paracetamol和Amorolfine。 Paracetamol子类负责创建氨加黄敏一类的药品, Amorolfine子类负责创建盐酸阿莫罗分一类的药品。
一个为某药店开发的应用程序需要使用Drug类的某个子类的实例为用户提供药品。但是药店的应用程序不能使用Drug的子类的构造方法直接创建对象,因为药店没有能力给出药品的各个成分的含量,只有药厂才有这样的能力。
---------------------------------------------------------------------------------------------------------------------------------