设计模式笔记
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
设计模式(Design Pattern)的原则
1、"开-闭"原则——模块应对扩展开放,而对修改关闭。(最最核心的原则)
2、里氏代换原则——如果调用的是父类的话,那么换成子类也完全可以运行。里氏代换原则是继承复用的一个基础。
子类overload方法的访问权限不能小于父类对应方法的访问权限
3、合成复用原则——要少用继承,多用合成关系来实现。(合成包括:组合,聚合)
4、依赖倒转原则——抽象不应该依赖与细节,细节应当依赖与抽象。要针对接口编程,而不是针对实现编程。
传递参数,或者在组合聚合关系中,尽量引用层次高的类。
5、接口隔离原则——每一个接口应该是一种角色,不多不少,不干不该干的事,该干的事都要干。(单一职责)
6、抽象类——好的继承关系中,只有叶节点是具体类,其他节点应该都是抽象类,也就是说具体类是不被继承的。
将尽可能多的共同代码放到抽象类中。
7、迪米特法则——最少知识原则。不要和陌生人说话。
创建型设计模式
简单工厂(静态工厂方法Static Factory Method模式)
简单工厂模式是由一个工厂对象来决定创造哪一种产品类的实例
简单工厂模式最大的优点在于工厂类中包含了必要的逻辑判断。
//产品接口---水果接口
public interface Fruit {
public void plant();
}
//产品----苹果类
public class Apple implements Fruit{
public void plant() {System.out.println("plant apple!"); }
}
//产品----草莓类
public class Strawberry implements Fruit{
public void plant() {System.out.println("plant Strawberry!");}
}
//工厂异常类
public class BadFruitException extends Exception{
public BadFruitException(String msg) {
super(msg); //调用父类的构造方法
}
}
//工厂----园丁类
public class FruitGardener {//静态工厂方法
public static Fruit factory(String which) throws BadFruitException {
if (which.equalsIgnoreCase("apple")) {
return new Apple();
} else if(which.equalsIgnoreCase("strawberry")){
return new Strawberry();
}else {
throw new BadFruitException("Bad fruit request");
}
}
}
//测试类
public class TestApp {
private void test(String fruitName) {
try {
Fruit f = FruitGardener.factory(fruitName);
System.out.println("恭喜!生产了一个水果对象:" + fruitName);
} catch (BadFruitException e) {
System.out.println("工厂目前不能生产产品:" + fruitName);
System.out.println(e.getMessage());//输出异常信息
}
}
public static void main(String args[]) {
TestApp t = new TestApp();
t.test("apple");
t.test("strawberry");
t.test("car"); //此处会抛异常,水果工厂能生产car(轿车)吗!
}
}
工厂方法(Factory Method)
定义一个用于创建对象的接口,让子类决定实例哪一个类。
工厂方法使一个类的实例化延迟到其子类。在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建的工作交给子类去做。这个核心工厂则变为抽象工厂角色,仅负责给出工厂子类必须实现的接口,而不接触哪一产品创建的细节。
工厂方法模式可以用来允许系统不修改具体工厂角色的情况下引进新产品
在工厂方法模式中,一般都有一个平行的等级结构,抽象工厂对应抽象产品,具体工厂对应具体产品
计算器工厂方法
//水果工厂
public interface FruitGardener { //工厂接口
public Fruit factory();
}
//苹果工厂
public class AppleGardener implements FruitGardener { //工厂方法public Fruit factory() {
Fruit f = new Apple();
System.out.println("水果工厂成功创建一个水果:苹果!");
return f;
}
}
//草莓工厂
public class StrawberryGardener implements FruitGardener { ///工厂方法public Fruit factory() {
Fruit f = new Strawberry();
System.out.println("水果工厂成功创建一个水果:草莓!");
return f;
}
} //测试类(客户端)
public class TestApp {
private FruitGardener f1, f2, f3;
private Fruit p1, p2, p3;
private void test() {
//实力化水果工厂
f1 = new AppleGardener();
f3 = new StrawberryGardener();
//从水果工厂生产水果
p1 = f1.factory();
p3 = f3.factory();
}
public static void main(String args[]) { TestApp test = new TestApp();
test.test();
}
}
抽象工厂模式(AbstractFactory)
每一个模式都是针对一定问题的解决方案,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式针对的是多个产品等级结果。
产品族:是指位于不同产品等级结构中,功能相关联的产品组成的家族。一般是位于不同的等级结构中的相同位置上。
每一个产品等级结构中有多少个具体的产品,就有多少个产品族,也就会在工厂等级结构中发现多少个具体工厂。
一般而言,有多少个产品等级结构,就会在工厂角色中发现多少个工厂方法。
具体工厂(工厂类)中有工厂方法(工厂类中的方法)
抽象工厂在农场系统中的应用:
// 两种抽象产品(两个结构等级):水果、蔬菜
interface Fruit {}
interface Veggie {}
// 四种具体产品:北方水果,热带水果,北方蔬菜,热带蔬菜// Northern Fruit
class NorthernFruit implements Fruit {
private String name;
NorthernFruit(String name) {}
String getName() {return name;}
void setName(String name){ = name;}
}
// TropicalFruit
class TropicalFruit implements Fruit {
private String name;
TropicalFruit(String name) {}
String getName() {return name;}
void setName(String name) { = name;} }
// NorthernVeggie
class NorthernVeggie implements Veggie {
private String name;
NorthernVeggie(String name) {}
String getName() {return name;}
void setName(String name) { = name;} }
// TropicalVeggie
class TropicalVeggie implements Veggie {
private String name;
TropicalVeggie(String name) {}