何为模式
经常使用的方案,公认为正确或相对正确
何为设计模式
一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结
设计模式分类
创建型模式
•简单工厂模式
•工厂方法模式
•抽象工厂模式
•建造者模式
•原型模式
结构型模式
•外观模式
•适配器模式
•装饰模式
•桥接模式
•组合模式
•享元模式
行为型模式
•观察者模式
•状态模式
•策略模式
•职责链模式
•命令模式
•中介者模式
•备忘录模式
•迭代器模式
设计模式详解
简单工厂模式
•定义:
–根据输入或上下文选择创建哪种对象。
•场景与功用:
–将对象的创建与使用分离
–集中处理共通创建步骤
•样例代码:
package
simplefactory;
class
BaseView {
}
abstract
class
PicView
extends
BaseView {
}
abstract
class
VideoView
extends
BaseView {
}
class
FeedPicView
extends
PicView {
}
class
FeedVideoView
extends
VideoView {
}
class
FeedFactory {
public
static
BaseView createView(String type) {
switch
(type) {
case
"pic"
:
return
new
FeedPicView();
case
"video"
:
return
new
FeedVideoView();
}
return
null
;
}
}
public
class
SimpleFactoryDemo {
public
static
void
main(String[] args) {
BaseView picView = FeedFactory.createView(
"pic"
);
BaseView videoView = FeedFactory.createView(
"video"
);
System.out.println(picView.getClass().getSimpleName() +
" "
+ videoView.getClass().getSimpleName());
}
}
|
工厂方法模式
•定义:
–定义一个用于创建对象的接口,让子类决定实例化哪一个类。
•场景与功用:
–使一个类的实例化延迟到其子类
–通过选择子工厂来生产对应的对象
–将对象的创建与使用分离
–抽象共通创建步骤
•样例代码:
package
factorymethod;
class
BaseView {
}
abstract
class
PicView
extends
BaseView {
}
abstract
class
VideoView
extends
BaseView {
}
class
FeedPicView
extends
PicView {
}
class
FeedVideoView
extends
VideoView {
}
abstract
class
ViewFactory {
abstract
public
BaseView createView();
}
class
PicFactory
extends
ViewFactory {
@Override
public
BaseView createView() {
return
new
FeedPicView();
}
}
class
VideoFactory
extends
ViewFactory {
@Override
public
BaseView createView() {
return
new
FeedVideoView();
}
}
public
class
FactoryMethodDemo {
public
static
void
main(String[] args) {
BaseView picView =
new
PicFactory().createView();
BaseView videoView =
new
VideoFactory().createView();
System.out.println(picView.getClass().getSimpleName() +
" "
+ videoView.getClass().getSimpleName());
}
}
|
抽象工厂方法
•定义:
–提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类
•场景与功用:
–两种以上产品系列
–系列之间,产品的种数相同、抽象相同
–将对象的创建与使用分离
–抽象共通创建步骤
•样例代码:
package
abstractfactory;
class
BaseView {
}
abstract
class
PicView
extends
BaseView {
}
abstract
class
VideoView
extends
BaseView {
}
class
FeedPicView
extends
PicView {
}
class
FeedVideoView
extends
VideoView {
}
class
RecommendPicView
extends
PicView {
}
class
RecommendVideoView
extends
VideoView {
}
abstract
class
ViewFactory {
abstract
PicView createPicView();
abstract
VideoView createVideoView();
}
class
FeedViewFactory
extends
ViewFactory {
@Override
PicView createPicView() {
return
new
FeedPicView();
}
@Override
VideoView createVideoView() {
return
new
FeedVideoView();
}
}
class
RecommendViewFactory
extends
ViewFactory {
@Override
PicView createPicView() {
return
new
RecommendPicView();
}
@Override
VideoView createVideoView() {
return
new
RecommendVideoView();
}
}
public
class
AbstractFactoryDemo {
public
static
void
main(String[] args) {
// 在feed列表中
displayViews(
new
FeedViewFactory());
// 在recommend列表中
displayViews(
new
RecommendViewFactory());
}
public
static
void
displayViews(ViewFactory factory) {
PicView picView = factory.createPicView();
VideoView videoView = factory.createVideoView();
System.out.println(picView.getClass().getSimpleName() +
" "
+ videoView.getClass().getSimpleName());
}
}
|
建造者模式
•定义:
–将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示
–表示可以理解为实现方式
•场景与功用
–算法实现方式与对象构造过程无关
–构造过程的抽象
•样例代码:
package
builder;
import
android.net.Uri;
public
class
BuilderDemo {
public
static
void
main(String[] args) {
StringBuilder sb =
new
StringBuilder();
sb.append(
"This "
);
sb.append(
"is "
);
sb.append(
"a "
);
sb.append(
"demo "
);
sb.append(
"for "
);
sb.append(
"Builder."
);
System.out.println(sb.toString());
}
public
static
void
uriBuilderDemo(){
Uri.Builder ub =
new
Uri.Builder();
ub.scheme(
"http"
);
ub.authority(
"api.sina.com:8080"
);
ub.appendPath(
"list.json"
);
ub.appendQueryParameter(
"wm"
,
"0560"
);
System.out.println(ub.build().toString());
}
}
|
原型模式
•定义:
–用原型对象指定创建对象的种类,并且通过拷贝这些原型对象创建新的对象
–又名“克隆模式”
•场景与功用:
–需要创建一个初始化代价较大的对象
–类自己决定哪些字段深拷贝哪些浅拷贝
•样例代码:
package
prototype;
import
java.util.ArrayList;
class
NewsItem
implements
Cloneable {
private
String id =
""
;
private
String title =
""
;
private
String source =
""
;
private
String link =
""
;
private
int
comment;
private
String category =
""
;
private
ArrayList
new
ArrayList
private
ArrayList
new
ArrayList
@Override
public
NewsItem clone()
throws
CloneNotSupportedException {
NewsItem obj = (NewsItem)
super
.clone();
obj.pv = (ArrayList
obj.monitor = (ArrayList
return
obj;
}
}
class
VideoNewsItem
implements
Cloneable {
private
VideoInfo video_info =
new
VideoInfo();
@Override
public
VideoNewsItem clone()
throws
CloneNotSupportedException {
VideoNewsItem item = (VideoNewsItem)
super
.clone();
item.video_info = video_info.clone();
return
item;
}
}
class
VideoInfo
implements
Cloneable {
private
String pic =
""
;
private
String url =
""
;
private
String runtime =
""
;
private
String playnumber =
""
;
private
String type =
""
;
@Override
public
VideoInfo clone()
throws
CloneNotSupportedException {
return
(VideoInfo)
super
.clone();
}
}
public
class
PrototypeDemo {
public
static
void
main(String[] args)
throws
CloneNotSupportedException {
VideoNewsItem item1 =
new
VideoNewsItem();
VideoNewsItem item2 = item1.clone();
System.out.println(item1==item2);
}
}
|
外观模式
•定义:
–为子系统中的一组接口提供一个一致的界面
•场景与功用
–调用旧系统或第三方系统
–调用接口繁杂的系统
–将常用子接口组合封装成为简单的新接口
适配器模式
•定义:
–将一个类的接口转换成使用者希望的接口形式
•分类:
–类适配器:继承适配
–对象适配器:委托适配
•场景:
–两个系统接口不兼容时
–双方系统都不易或不能修改时
装饰模式
•定义:
–动态地给一个对象添加一些额外的职责。
•场景与功用:
–将类的核心职能和额外的装饰功能分离,并且可以随意重用或选用装饰逻辑。
•样例代码:
package
decorator;
interface
Number {
public
String getNumber();
}
class
PhoneNumber
implements
Number {
private
String number;
public
PhoneNumber(String number) {
this
.number = number;
}
@Override
public
String getNumber() {
return
number;
}
}
class
CityDecorator
implements
Number {
private
Number number;
public
CityDecorator(Number number) {
this
.number = number;
}
@Override
public
String getNumber() {
return
"010-"
+ number.getNumber();
}
}
class
NationDecorator
implements
Number {
private
Number number;
public
NationDecorator(Number number) {
this
.number = number;
}
@Override
public
String getNumber() {
return
"+86-"
+ number.getNumber();
}
}
class
AsteriskDecorator
implements
Number {
private
Number number;
public
AsteriskDecorator(Number number) {
this
.number = number;
}
@Override
public
String getNumber() {
return
"***"
+ number.getNumber() +
"***"
;
}
}
public
class
DecoratorDemo {
public
static
void
main(String[] args) {
Number number =
null
;
////////////////////////////////
number =
new
PhoneNumber(
"82675588"
);
number =
new
CityDecorator(number);
number =
new
NationDecorator(number);
number =
new
AsteriskDecorator(number);
System.out.println(number.getNumber());
////////////////////////////////
number =
new
PhoneNumber(
"82675588"
);
number =
new
CityDecorator(number);
number =
new
AsteriskDecorator(number);
System.out.println(number.getNumber());
////////////////////////////////
number =
new
PhoneNumber(
"82675588"
);
number =
new
AsteriskDecorator(number);
number =
new
CityDecorator(number);
System.out.println(number.getNumber());
}
}
|
桥接模式
•定义:
–将抽象部分与它的实现部分分离,使它们都可以独立地变化。
•组合/聚合复用原则:
–尽量使用组合/聚合,而不是使用类继承
•场景与功用
–一个抽象出现了多个维度的变化
–控制类爆炸,以减弱维度间的耦合
•样例代码:
不使用桥接
package
bridge;
import
com.sina.news.R;
import
com.sina.news.bean.NewsItem;
class
PicNewsItem
extends
NewsItem {
//category = "cms";
public
int
getIcon() {
return
-
1
;
}
}
class
VideoNewsItem
extends
NewsItem {
//category = "video";
public
int
getIcon() {
return
R.drawable.ic_list_item_video_normal;
}
}
class
RecommendPicNewsItem
extends
NewsItem {
//category = "cms";
public
int
getIcon() {
return
-
1
;
}
}
class
RecommendVideoNewsItem
extends
NewsItem {
//category = "video";
public
int
getIcon() {
return
R.drawable.ic_list_item_video_normal;
}
}
public
class
NonBridgeDemo {
public
static
void
main(String[] args) {
}
}
|
使用桥接
package
bridge;
import
com.sina.news.R;
import
com.sina.news.bean.NewsItem;
abstract
class
Category {
abstract
public
int
getIcon();
}
class
PicCategory
extends
Category {
@Override
public
int
getIcon() {
return
-
1
;
}
}
class
VideoCategory
extends
Category {
@Override
public
int
getIcon() {
return
R.drawable.ic_list_item_video_normal;
}
}
class
NormalNewsItem
extends
NewsItem {
// Category category = new PicCategory();
Category category =
new
VideoCategory();
}
class
RecommendNewsItem
extends
NewsItem {
Category category =
new
PicCategory();
// Category category = new VideoCategory();
}
public
class
BridgeDemo {
public
static
void
main(String[] args) {
}
}
|
组合模式
•定义:
–将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
•场景与功用
–需要树形数据结构时
–树枝与树叶没有区别,使用时可以一致对待
•样例代码:
package
composite;
import
java.util.ArrayList;
import
java.util.Collection;
import
java.util.List;
class
View {
}
class
ViewGroup
extends
View {
private
List
new
ArrayList
public
void
add(View v) {
children.add(v);
}
public
Collection
return
new
ArrayList
}
}
public
class
CompositeDemo {
public
static
void
main(String[] args) {
ViewGroup vg1 =
new
ViewGroup();
ViewGroup vg2 =
new
ViewGroup();
ViewGroup vg3 =
new
ViewGroup();
ViewGroup vg4 =
new
ViewGroup();
ViewGroup vg5 =
new
ViewGroup();
// @formatter:off
/* vg1
* |--vg2
* | |--vg4
* | |--vg5
* |
* |--vg3
*/
// @formatter:on
vg1.add(vg2);
vg1.add(vg3);
vg2.add(vg4);
vg2.add(vg5);
}
}
|
享元模式
•定义:
–运用共享技术有效地支持大量细粒度的对象。
•场景与功用:
–同一时段使用不多,而总体数量庞大的可共享对象
•可共享对象:
–初始化代价较大(内部状态)
–可变属性较少(外部状态)
观察者模式
•定义:
–定义一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
•场景与功用
–对象联动,一个对象改变同时需要更新其他对象
–对象定义时不知道有多少对象有待改变
•样例代码:
package
observer;
import
java.util.Observable;
import
java.util.Observer;
public
class
ObserverDemo {
public
static
int
SHARE_TYPE_NORMAL =
1
;
public
static
int
SHARE_TYPE_EXCLUSIVE =
2
;
private
CheckBox mCheckboxEnable =
new
CheckBox();
private
SelectBox mSelectShareType =
new
SelectBox();
private
TextBox mTextShareName =
new
TextBox();
private
CheckBox mCheckboxReadOnly =
new
CheckBox();
private
Label mLabelDescrpiton =
new
Label();
abstract
class
View
extends
Observable
implements
Observer {
private
boolean
disabled =
false
;
public
void
setDisabled(
boolean
disabled) {
this
.disabled = disabled;
}
public
boolean
isDisabled() {
return
this
.disabled;
}
}
class
SelectBox
extends
View {
private
int
selected;
public
void
setSelect(
int
index) {
this
.selected = index;
setChanged();
notifyObservers();
}
public
int
getSelect() {
return
selected;
}
@Override
public
void
update(Observable observable, Object data) {
if
(mCheckboxEnable.isChecked()) {
this
.setDisabled(
true
);
}
else
{
this
.setDisabled(
false
);
}
}
}
class
TextBox
extends
View {
private
String text;
public
void
setText(String text) {
this
.text = text;
setChanged();
notifyObservers();
}
public
String getText() {
return
text;
}
@Override
public
void
update(Observable observable, Object data) {
if
(mCheckboxEnable.isChecked()) {
this
.setDisabled(
true
);
}
else
{
this
.setDisabled(
false
);
}
}
}
class
CheckBox
extends
View {
private
boolean
checked;
public
void
setChecked(
boolean
checked) {
this
.checked = checked;
setChanged();
notifyObservers();
}
public
boolean
isChecked() {
return
checked;
}
@Override
public
void
update(Observable observable, Object data) {
if
(
this
== mCheckboxEnable) {
return
;
}
if
(
this
== mCheckboxReadOnly) {
if
(mSelectShareType.getSelect() == SHARE_TYPE_NORMAL) {
this
.setDisabled(
false
);
}
else
if
(mSelectShareType.getSelect() == SHARE_TYPE_EXCLUSIVE) {
this
.setChecked(
true
);
this
.setDisabled(
true
);
}
}
}
}
class
Label
extends
View {
private
String text;
@Override
public
void
update(Observable observable, Object data) {
if
(!mCheckboxEnable.isChecked()) {
this
.text =
"Disabled"
;
return
;
}
this
.text = mSelectShareType.toString() + mTextShareName.toString()
+ mCheckboxReadOnly.toString();
}
public
String getText() {
return
text;
}
}
public
ObserverDemo() {
mCheckboxEnable.addObserver(mSelectShareType);
mCheckboxEnable.addObserver(mTextShareName);
mCheckboxEnable.addObserver(mCheckboxReadOnly);
mCheckboxEnable.addObserver(mLabelDescrpiton);
mSelectShareType.addObserver(mCheckboxReadOnly);
mSelectShareType.addObserver(mLabelDescrpiton);
mTextShareName.addObserver(mCheckboxReadOnly);
mTextShareName.addObserver(mLabelDescrpiton);
}
public
static
void
main(String[] args) {
}
}
|
状态模式
•定义:
–当一个对象的内在状态改变时,允许改变其行为,这个对象看起来是改变了其类。
•场景与功用
–控制一个对象状态转换的条件过于复杂
–把状态转换逻辑封装到一系列类中,将逻辑局部化
–降低状态之间的耦合
•样例代码:
package
state;
class
Activity {
protected
State state;
abstract
class
State {
abstract
void
next();
}
class
BootImageState
extends
State {
@Override
void
next() {
if
(isFirstRun()) {
state =
new
FinishState();
}
else
{
showBootImage();
state =
new
AdState();
}
}
}
class
AdState
extends
State {
@Override
void
next() {
if
(isAdReady()) {
showAd();
state =
new
FinishState();
}
else
{
state =
new
CoverStoryState();
}
}
}
class
CoverStoryState
extends
State {
@Override
void
next() {
if
(isCoverStoryReady()) {
showCoverStory();
}
state =
new
FinishState();
}
}
class
FinishState
extends
State {
@Override
void
next() {
state =
null
;
enterMainActivity();
}
}
private
boolean
isFirstRun() {
return
false
;
}
private
void
showBootImage(){}
private
boolean
isAdReady() {
return
true
;
}
private
void
showAd() {
}
private
boolean
isCoverStoryReady() {
return
true
;
}
private
void
showCoverStory() {
}
public
void
enterMainActivity() {
// MainActivity.start();
// this.finish();
}
public
void
execute() {
while
(state !=
null
) {
state.next();
}
}
}
public
class
StateDemo {
public
static
void
main(String[] args) {
Activity powerOn =
new
Activity();
powerOn.execute();
}
}
|
策略模式
•定义:
–定义算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法使用者可以不改变实现的情况下灵活切换算法。
•场景与功用:
–减少了算法使用者与算法之间的耦合
•扩展:
–可以封装任何类型的变化
•样例代码:
package
strategy;
import
java.util.Arrays;
import
java.util.Collections;
import
java.util.Comparator;
import
java.util.List;
class
Person {
private
final
int
id;
private
final
String name;
public
Person(
int
id, String name) {
this
.id = id;
this
.name = name;
}
public
int
getId() {
return
id;
}
public
String getName() {
return
name;
}
public
String toString() {
return
"{"
+ id +
", "
+ name +
"}"
;
}
}
class
PersonComparatorById
implements
Comparator
@Override
public
int
compare(Person p0, Person p1) {
return
p0.getId() - p1.getId();
}
}
class
PersonComparatorByName
implements
Comparator
@Override
public
int
compare(Person p0, Person p1) {
return
p0.getName().compareTo(p1.getName());
}
}
public
class
StrategyDemo {
public
static
void
main(String[] args) {
List
new
Person(
80
,
"Mick"
),
new
Person(
90
,
"Racheal"
),
new
Person(
15
,
"Jack"
),
new
Person(
21
,
"Don"
),
new
Person(
93
,
"Wislee"
),
new
Person(
65
,
"Lucy"
),
new
Person(
70
,
"Nazu"
));
Collections.sort(persons,
new
PersonComparatorById());
System.out.println(
"Sorted by ID : "
+ persons);
Collections.sort(persons,
new
PersonComparatorByName());
System.out.println(
"Sorted by Name : "
+ persons);
}
}
|
职责链模式
•定义:
–将请求的可能接收者组织成链,让请求延这条链传递直到有一个接收者处理它为止。
•相关概念:
–AOP:面向切片编程
•场景与功用
–请求处理逻辑经常变化的场合
–各处理逻辑之间解耦合
•样例代码:
package
responsibilitychain;
import
android.content.Intent;
import
android.net.ConnectivityManager;
abstract
class
IntentHandler {
private
final
IntentHandler nextHandler;
public
IntentHandler(IntentHandler nextHandler) {
this
.nextHandler = nextHandler;
}
abstract
public
boolean
process(Intent intent);
public
void
handle(Intent intent) {
if
(process(intent) && nextHandler !=
null
) {
nextHandler.process(intent);
}
}
}
class
ActionValidateHandler
extends
IntentHandler {
public
ActionValidateHandler(IntentHandler nextHandler) {
super
(nextHandler);
}
@Override
public
boolean
process(Intent intent) {
if
(intent.getAction() ==
null
) {
return
false
;
}
return
true
;
}
}
class
NetworkChangeHandler
extends
IntentHandler {
public
NetworkChangeHandler(IntentHandler nextHandler) {
super
(nextHandler);
}
@Override
public
boolean
process(Intent intent) {
if
(intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
// 处理网络变化逻辑
}
return
true
;
}
}
class
SaveIntentHandler
extends
IntentHandler {
public
SaveIntentHandler(IntentHandler nextHandler) {
super
(nextHandler);
}
@Override
public
boolean
process(Intent intent) {
save((Intent) intent.clone());
return
true
;
}
private
void
save(Intent intent) {
// 保存intent
}
}
class
Receiver {
public
void
receive(Intent intent) {
IntentHandler saveHandler =
new
SaveIntentHandler(
null
);
IntentHandler netHandler =
new
NetworkChangeHandler(saveHandler);
IntentHandler actionHandler =
new
ActionValidateHandler(netHandler);
actionHandler.handle(intent);
}
}
public
class
ChainOfResponsibilityDemo {
public
static
void
main(String[] args) {
new
Receiver().receive(
new
Intent());
}
}
|
命令模式
•定义:
–将一个请求(命令)封装成一个对象,从而可用不同的请求对客户端进行参数化。
•场景与功用
–多方请求容易冲突的场合
–请求可以排队,记录日志,重做以及撤销
中介者模式
•定义:
–用一个中介对象来封装一系列对象的交互。
•场景与功用:
–各对象不需要显式地相互引用,独立变化互不干涉,降低耦合
备忘录模式
•定义:
–在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可将该对象恢复到原先保存的状态。
•场景与功用
–功能比较复杂,但需要维护或记录属性历史的类
–需要保存的属性只是部分属性,用原型模式的代价过大时
迭代器模式
•定义:
–提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。
•场景与功用
–自定义聚合数据
–封装聚合数据的内部实现,与使用者的数据结构解耦合
•样例代码:
package
iterator;
import
java.util.ArrayList;
import
java.util.Collection;
import
java.util.Iterator;
import
java.util.List;
import
com.sina.news.bean.NewsItem;
class
NewsItemList
implements
Iterable
private
List
null
;
public
NewsItemList() {
items =
new
ArrayList
}
public
void
add(NewsItem item) {
items.add(item);
}
public
void
addAll(Collection
items.addAll(c);
}
@Override
public
Iterator
return
new
Iterator
private
int
index = -
1
;
@Override
public
boolean
hasNext() {
return
index +
1
< items.size();
}
@Override
public
NewsItem next() {
return
items.get(++index);
}
@Override
public
void
remove() {
items.remove(index);
}
};
}
}
public
class
IteratorDemo {
public
static
void
main(String[] args) {
NewsItemList itemList =
new
NewsItemList();
itemList.add(
new
NewsItem());
itemList.add(
new
NewsItem());
itemList.add(
new
NewsItem());
itemList.add(
new
NewsItem());
itemList.add(
new
NewsItem());
Iterator
while
(it.hasNext()) {
System.out.println(it.next().hashCode());
}
// for(NewsItem item : itemList){
// System.out.println(item.hashCode());
// }
}
}
|