设计软件的几个原则,这个也是设计模式的精髓所在:
1.开-闭原则
1).客户的需求是不稳定的,通过扩展已有的软件系统而不是通过修改软件系统来满足客户的需求,这样的软件系统就满足开-闭原则,即软件系统要有一定的灵活性和适应性。
2).已有的模块,特别是抽象层的模块不能修改,保证软件系统的稳定性和延续性。
解决问题的关键是抽象化,把它与具体实现分离开来。接口(interface),抽象类的应用
对可变性封装:将可变性封装到一个对象里。
2.抽象类
抽象类不会有实例,一般作为父类为子类继承,一般包含这个系的共同属性和方法。
注意:好的继承关系中,只有叶节点是具体类,其他节点应该都是抽象类,也就是说具体类
是不被继承的。将尽可能多的共同代码放到抽象类中。
3.里氏代换原则
在有基类出现的地方,子类均可以替代。
当两个具体类关系违反里氏代换原则时,一种办法是抽象出一个基类,作为这两个类的父类,
一种是应用组合聚合关系建立关系。
不要为了使用某些类的方法(功能)而滥用继承。
4 依赖倒转原则
抽象不应该依赖与细节,细节应当依赖与抽象。
要针对接口编程,而不是针对实现编程。
传递参数,或者在组合聚合关系中,尽量引用层次高的类。
主要是在构造对象时可以动态的创建各种具体对象,当然如果一些具体类比较稳定,就不必在弄一个抽象类做它的父类,这样有画舌添足的感觉
5 接口隔离原则
定制服务的例子,每一个接口应该是一种角色,不多不少,不干不该干的事,该干的事都要干
6 合成/聚合原则
尽量使用合成聚合原则,少用慎用继承。
合成:一荣俱荣,一损俱损,整体和部分的生命周期是一样的
聚合:部分可以是整体的一部分,也可以脱离整体而存在。
区分Has a和Is a的问题
7 迪米特法则
最少知识原则。不要和陌生人说话。
简单工厂模式
- abstract
class Fruit{ - }
-
-
- class
Apple extends Fruit{ - }
-
-
- class
Orange extends Fruit{ - }
-
-
- class
FruitFactory{ -
pulic static Fruit getFruit(String fruitType){ -
if (“apple” == fruitType){ -
return new Apple(); -
} else if (“orange” == fruitType) { -
return new Orange(); -
} -
} - }
工厂方法模式
- interface
IFruitFactory{ -
puhlic Fruit getFruit(); - }
- class
AppleFactory implements IFruitFactory{ -
public Fruit getFruit(){ -
//生产苹果 -
return new Apple(); -
} - }
单例模式
- class
Singleton{ -
private static Singleton singleton = null; -
public static Singleton getInstance(){ -
if(null == singleton){ -
singleton = new Singleton(); -
} -
return singleton; -
} -
public String otherOperation(){ -
//方法实现 -
} - }
适配器模式
- interface
Powerable{ -
110v provide(); - }
- class
110v { - }
- class
220v { - }
- class
110vPower implements Powerable{ -
public 110v provide(){ -
//提供 110v 电压 -
} - }
- class
220vPower { -
public 220v provide(){ -
//提供 220v 电压 -
} - }
- class
220vAdapter implements Powerable{ -
public 110v provide(){ -
110v voltage = null; -
220vPower power = new 220vPower(); -
//转换过程,@!@#$%^ -
return voltage; -
} - }
组合模式
- abstract
class Hardware{ - }
-
- class
Mainboard extends Hardware{ - }
-
- class
Memory extends Hardware{ - }
-
- class
Display extends Hardware( - }
-
- class
NetworkAdapter extends Hardware{ - }
- class
Computer extends Hardware[ -
private List parts = new Arraylist(); -
public List add(Hardware hardware){ -
parts.add(hardware); -
return parts; -
} - }
abstract class Hardware{ } class Mainboard extends Hardware{ } class Memory extends Hardware{ } class Display extends Hardware( } class NetworkAdapter extends Hardware{ } class Computer extends Hardware[ private List parts = new Arraylist(); public List add(Hardware hardware){ parts.add(hardware); return parts; } }
Client:
- Computer
computer = new Computer(); - Mainboard
mainboard = new Mainboard(); - NetworkAdapter
networkAdapter = new NetworkAdapter(); - Display
display = new Display(); - Memory
memory = new Memory(); - computer
.add(mainboad) -
.add(networkAdapter) -
.add(display) -
.add(memory);
- class
CallCenter{ -
public void solve(Customer customer){ -
//接受客户提出的问题 -
operator.acceptProblem(customer.getProblem()); -
boolean canSolved = operator.solve(); -
if (!canSolved) { -
//如果不能解决,则请求其它人帮助。 -
operator.askHelp(); -
} -
} - }
-
- class
Customer{ -
public void call(CallCenter callCenter){ -
callCenter.solve(this); -
} - }
-
- class
Operator{ - }
class CallCenter{ public void solve(Customer customer){ //接受客户提出的问题 operator.acceptProblem(customer.getProblem()); boolean canSolved = operator.solve(); if (!canSolved) { //如果不能解决,则请求其它人帮助。 operator.askHelp(); } } } class Customer{ public void call(CallCenter callCenter){ callCenter.solve(this); } } class Operator{ }
Client:
- CallCenter
callCenter = new CallCenter(); - Custom
aCustomer = new Customer(); - aCustomer.call(callCenter);
CallCenter callCenter = new CallCenter(); Custom aCustomer = new Customer(); aCustomer.call(callCenter);
这里对客户来讲,与他接触的只有一个接口,就是接线员,最后的结果是解决他的问题。接线员可以直接解决,如果他不能解决,它可以选择请求其它人的帮助去解决这个问题。客户是不关心接线员在内部做了什么。
代理模式
- class
FileDownloader( -
public download(File file); - }
-
- class
File{ - }
-
- //一般代理类使用
Proxy 后缀 - class
FileDownloaderProxy{ -
FileDownloaderProxy(FileDownloader downloader){ -
this.downloader = downloader; -
} -
private FileDownloader downloader; -
public download(File file){ -
//这里可以添加通知,通知用户开始下载文件 -
notifyDownloadWillStart(); -
//调用代理目标类的方法,进行下载文件 -
this.downloader.download(file); -
//这里可以添加通知,通知用户文件下载完成 -
notifyDownloadIsComplete (); -
} -
private void notifyDownloadWillStart(){ -
System.out.println(“下载开始...”); -
} -
private void notifyDownloadIsComplete (){ -
System.out.println(“下载完成!”); -
} - }
class FileDownloader( public download(File file); } class File{ } //一般代理类使用 Proxy 后缀 class FileDownloaderProxy{ FileDownloaderProxy(FileDownloader downloader){ this.downloader = downloader; } private FileDownloader downloader; public download(File file){ //这里可以添加通知,通知用户开始下载文件 notifyDownloadWillStart(); //调用代理目标类的方法,进行下载文件 this.downloader.download(file); //这里可以添加通知,通知用户文件下载完成 notifyDownloadIsComplete(); } private void notifyDownloadWillStart(){ System.out.println(“下载开始...”); } private void notifyDownloadIsComplete (){ System.out.println(“下载完成!”); } }
Client:
- FileDownloaderProxy
proxy = new FileDownloaderProxy( new FileDownloader()); - proxy.downlaod(file);
FileDownloaderProxy proxy = new FileDownloaderProxy( new FileDownloader()); proxy.downlaod(file);
代理模式提供了一种间接性,可以做一些附加工作,比如记录日志,触发一些事件等,Spring 框架中大量使用了这个模式来进行 AOP 编程。