為子系統中的一組接口提供一個一致的界面,Facade模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。
1.當你要為一個復雜子系統提供一個簡單接口時。子系統往往因為不斷演化而變得越來越 復雜。大多數模式使用時都會產生更多更小的類。這使得子系統更具可重用性,也更容 易對子系統進行定制,但這也給那些不需要定制子系統的用戶帶來一些使用上的困難。 Facade可以提供一個簡單的缺省視圖,這一視圖對大多數用戶來說已經足夠,而那些需 要更多的可定制性的用戶可以越過facade層。
2.客戶程序與抽象類的實現部分之間存在著很大的依賴性。引入facade將這個子系統與客 戶以及其他的子系統分離,可以提高子系統的獨立性和可移植性。
3.當你需要構建一個層次結構的子系統時,使用facade模式定義子系統中每層的入口點。 如果子系統之間是相互依賴的,你可以讓它們僅通過facade進行通訊,從而簡化了它們 之間的依賴關系。
例子:
外觀類:
public class Facade {
ServiceA sa;
ServiceB sb;
ServiceC sc;
public Facade() {
sa = new ServiceAImpl();
sb = new ServiceBImpl();
sc = new ServiceCImpl();
}
public void methodA() {
sa.methodA();
sb.methodB();
}
public void methodB() {
sb.methodB();
sc.methodC();
}
public void methodC() {
sc.methodC();
sa.methodA();
}
}
接口和接口的實現類:
public interface ServiceA {
void methodA() ;
}
public class ServiceAImpl implements ServiceA{
@Override
public void methodA() {
System.out.println("這是服務A");
}
}
public interface ServiceB {
void methodB() ;
}
public class ServiceBImpl implements ServiceB{
@Override
public void methodB() {
System.out.println("這是服務B");
}
}
public interface ServiceC {
void methodC() ;
}
public class ServiceCImpl implements ServiceC{
@Override
public void methodC() {
System.out.println("這是服務C");
}
}
測試類:
public class Test {
public static void main(String[] args) {
ServiceA sa = new ServiceAImpl();
ServiceB sb = new ServiceBImpl();
sa.methodA();
sb.methodB();
System.out.println("========");
//facade
Facade facade = new Facade();
facade.methodA();
facade.methodB();
facade.methodC();
}
}
運用共享技術有效地支持大量細粒度的對象。
1.一次性實現一個算法的不變的部分,并將可變的行為留給子類來實現。
2.各子類中公共的行為應被提取出來并集中到一個公共父類中以避免代碼重復。 首先識別現有代碼中的不同之處,并且將不同之處分離為新的操作。 最后,用一個調用這些新的操作的模板方法來替換這些不同的代碼。
3.控制子類擴展。
例子;
享元接口:
public interface Flyweight {
void action(int arg);
}
享元接口的實現類:
public class FlyweightImpl implements Flyweight{
@Override
public void action(int arg) {
System.out.println("參數值: " + arg);
}
}
產生精度對象的工廠類:
public class FlyweightFactory {
private static Map<String,Flyweight> flyweightsMap = new HashMap<String,Flyweight>();
public FlyweightFactory(String arg) {
System.out.println("-----------------");
flyweightsMap.put(arg, new FlyweightImpl());
}
public static Flyweight getFlyweight(String key) {
if (flyweightsMap.get(key) == null) {
flyweightsMap.put(key, new FlyweightImpl());
}
return (Flyweight) flyweightsMap.get(key);
}
public static int getSize() {
return flyweightsMap.size();
}
}
測試類:
public class Test {
public static void main(String[] args) {
Flyweight fly1 = FlyweightFactory.getFlyweight("a");
fly1.action(1);
Flyweight fly2 = FlyweightFactory.getFlyweight("a");
System.out.println(fly1 == fly2);
Flyweight fly3 = FlyweightFactory.getFlyweight("c");
fly3.action(3);
Flyweight fly4 = FlyweightFactory.getFlyweight("d");
fly4.action(4);
Flyweight fly5 = FlyweightFactory.getFlyweight("e");
fly5.action(5);
System.out.println(FlyweightFactory.getSize());
}
}
代理模式實現了類與類之間直接調用的解耦,例子:
代理模式主要使用了java的多態,干活的是被代理類,代理類主要的接活
,把活交給幕后的被代理類做,代理類和被代理類實現同一個接口。
被代理類的接口:
public interface Object {
void action();
}
被代理類的接口實現類:
public class ObjectImpl implements Object{
public void action() {
System.out.println("========");
System.out.println("========");
System.out.println("這是被代理的類");
System.out.println("========");
System.out.println("========");
}
}
代理類:
public class ProxyObject implements Object{
Object obj;
public ProxyObject() {
System.out.println("這是代理類");
obj = new ObjectImpl();
}
public void action() {
System.out.println("代理開始");
obj.action();
System.out.println("代理結束");
}
}
測試類:
public class Test {
public static void main(String[] args) {
Object obj = new ProxyObject();
obj.action();
}
}
定義一系列的算法,把它們一個個封裝起來,并且使它們可相互替換。本模式使得算法可獨立于使用它的客戶而變化。
適合場合:
* 1.以不同的格式保存文件
* 2.以不同的算法壓縮文件
* 3.以不同的算法截取圖形
* 4.以不同的格式輸出數據的圖形,曲線,框圖等
策略接口:
public interface Strategy {
void method();
}
策略接口實現類:
public class StrategyImplA implements Strategy{
public void method() {
System.out.println("這是第一個實現a");
}
}
public class StrategyImplB implements Strategy{
public void method() {
System.out.println("這是第二個實現b");
}
}
public class StrategyImplC implements Strategy{
public void method() {
System.out.println("這是第三個實現c");
}
}
調用類:
public class Context {
Strategy stra;
public Context(Strategy stra) {
this.stra = stra;
}
public void doMethod() {
stra.method();
}
}
測試:
public class Test {
public static void main(String[] args) {
Context ctx = new Context(new StrategyImplA());
ctx.doMethod();
ctx = new Context(new StrategyImplB());
ctx.doMethod();
ctx = new Context(new StrategyImplC());
ctx.doMethod();
}
}
命令模式就是將一組對象的相似行為,進行了抽象,將調用者與被調用者之間進行解耦,提
高了應用的靈活性。命令模式將調用的目標對象的一些異構性給封裝起來,通過統一的方式來為調用者提供服務。
適用場景
1、當一個應用程序調用者與多個目標對象之間存在調用關系時,并且目標對象之間的操作很類似的時候。
2、例如當一個目標對象內部的方法調用太復雜,或者內部的方法需要協作才能完成對象的某個特點操作時。
3、有時候調用者調用目標對象后,需要回調一些方法。
例子:
命令接口:
public interface Commond {
public void execute();
}
命令接口實現類:
public class LightOnCommond implements Commond{
private Light light;
public LightOnCommond(Light light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
}
命令的調用者:
public class Light {
public void on() {
System.out.println("燈亮了");
}
}
public class TurnTvCommond implements Commond {
private Tv tv;
public TurnTvCommond(Tv tv) {
this.tv = tv;
}
@Override
public void execute() {
tv.turn();
}
}
public class Tv {
public void turn() {
System.out.println("調臺");
}
}
同時執行的多個命令數組
public class MracoCommond implements Commond{
private Commond[] commonds;
public MracoCommond(Commond...commonds) {
this.commonds = commonds;
}
@Override
public void execute() {
for(Commond cmd : commonds) {
cmd.execute();
}
}
}
命令的包裝類,
public class RemoteContro {
private List<Commond> commondList = new ArrayList<Commond>();
public void setCommond(Commond commond) {
commondList.add(commond);
}
public void buttonWasPressed(int index){
commondList.get(index-1).execute();
}
}
public class Test {
public static void main(String[] args) {
Light light = new Light();
LightOnCommond loc = new LightOnCommond(light);
Tv tv = new Tv();
TurnTvCommond ttc = new TurnTvCommond(tv);
MracoCommond mc = new MracoCommond(loc,ttc);
RemoteContro rc = new RemoteContro();
rc.setCommond(ttc);
rc.setCommond(loc);
rc.setCommond(mc);
//rc.buttonWasPressed(3);
//rc.buttonWasPressed(1);
rc.buttonWasPressed(2);
}
}
當輸入123不同時,調用的命令不同,實現了多個命令的包裝
1.把依賴類(Service)和被依賴類(Dao)全部交給Spring管理
2.依賴類中提供被依賴類的set方法
3.在xml中進行配置
當把一個類交給spring管理是要給出一個無參數的構造方法給spring使用
<bean id="person" class="com.yjw.bean.Person1" factory-method="getPerson1" scope="prototype">
</bean>
scope="prototype"是創建多例,不配置此項,默認單例
或者lazy-init值設置為true
public class Person1 implements Person{
private Person1(String s){
System.out.println(s);
}
public void say() {
System.out.println("00000000000000");
}
public static Person1 getPerson1(){
return new Person1("pppppppppp");
}
}
<bean id="person" class="com.yjw.bean.Person1" factory-method="getPerson1">
public class Test {
public static void main(String[] args) {
ApplicationContext ctx =new ClassPathXmlApplicationContext("applicationContext.xml");
// UserService userservice =(UserService) ctx.getBean("person");
/* User u = new User();
u.setUsername("qq");
u.setPassword("qq");
userservice.save(u);*/
Person person = (Person) ctx.getBean("person");
person.say();
}
}
概述:
定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都得到通知并被自動更新。
適用性:
1.當一個抽象模型有兩個方面,其中一個方面依賴于另一方面。 將這二者封裝在獨立的對象中以使它們可以各自獨立地改變和復用。 2.當對一個對象的改變需要同時改變其它對象,而不知道具體有多少對象有待改變。 3.當一個對象必須通知其它對象,而它又不能假定其它對象是誰。
我們以天氣預報的服務為例,安卓和諾基亞購買天氣預報的服務,也可以停用服務:
天氣預報主體的接口:
public interface Subject {
public void zhuce(Observer observer);
public void remove(Observer observer);
public void tongzhi();
}
天氣預報的實現類:
public class WeatherData implements Subject {
private int low;
private int hight;
private String weather;
private List<Observer> list = new ArrayList<Observer>();
public void setData(int low, int hight, String weather) {
this.low = low;
this.hight = hight;
this.weather = weather;
tongzhi();
}
public int getLow() {
return low;
}
public int getHight() {
return hight;
}
public String getWeather() {
return weather;
}
public void zhuce(Observer observer) {
if (!list.contains(observer)) {
list.add(observer);
}
}
public void remove(Observer observer) {
if (list.contains(observer)) {
list.remove(observer);
}
}
public void tongzhi() {
for (Observer o : list) {
o.update(getLow(), getHight(), getWeather());
}
}
}
觀察者的接口:
public interface Observer {
void remove();
void update(int low, int hight, String weather);
}
觀察者的實現類:
public class Android implements Observer {
private Subject subject;
public Android() {
}
public Android(Subject subject) {
this.subject = subject;
this.subject.zhuce(this);
}
public void update(int low, int hight, String weather) {
System.out.println("android" + low + "" + hight + weather);
}
public void remove() {
subject.remove(this);
}
}
public class Nokia implements Observer{
private Subject subject;
public Nokia(){}
public Nokia(Subject subject){
this.subject = subject;
this.subject.zhuce(this);
}
public void update(int low, int hight, String weather) {
System.out.println("nokia:"+low+"-"+hight+"-"+weather);
}
public void remove(){
subject.remove(this);
}
}
測試類:
public class Test {
public static void main(String[] args) {
WeatherData wd = new WeatherData();
wd.setData(1, 22, "晴朗");
Android a = new Android(wd);
wd.tongzhi();
a.remove();
Nokia n = new Nokia(wd);
n.remove();
wd.tongzhi();
}
}
狀態模式
定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都得到通知并被自動更新。
用性:1.一個對象的行為取決于它的狀態,并且它必須在運行時刻根據狀態改變它的行為。
2.一個操作中含有龐大的多分支的條件語句,且這些分支依賴于該對象的狀態。
這個狀態通常用一個或多個枚舉常量表示。
通常,有多個操作包含這一相同的條件結構。
State模式將每一個條件分支放入一個獨立的類中。
這使得你可以根據對象自身的情況將對象的狀態作為一個對象,這一對象可以不依賴于其他對象而獨立變化。
狀態模式在工作流或游戲等各種系統中有大量使用,甚至是這些系統的核心功能設計,例如
政府OA中,一個批文的狀態有多種:未辦;正在辦理;正在批示;正在審核;已經完成等
各種狀態,使用狀態機可以封裝這個狀態的變化規則,從而達到擴充狀態時,不必涉及到狀
態的使用者。
在網絡游戲中,一個游戲活動存在開始;開玩;正在玩;輸贏等各種狀態,使用狀態模式就
可以實現游戲狀態的總控,而游戲狀態決定了游戲的各個方面,使用狀態模式可以對整個游
戲架構功能實現起到決定的主導作用。
狀態模式實質:
使用狀態模式前,客戶端外界需要介入改變狀態,而狀態改變的實現是瑣碎或復雜的。
使用狀態模式后,客戶端外界可以直接使用事件Event實現,根本不必關心該事件導致如
何狀態變化,這些是由狀態機等內部實現。
這是一種Event-condition-State,狀態模式封裝了condition-State部分。
每個狀態形成一個子類,每個狀態只關心它的下一個可能狀態,從而無形中形成了狀態轉換
的規則。如果新的狀態加入,只涉及它的前一個狀態修改和定義。
狀態轉換有幾個方法實現:一個在每個狀態實現next(),指定下一個狀態;還有一種方法,
設定一個StateOwner,在StateOwner設定stateEnter狀態進入和stateExit狀
態退出行為。
狀態從一個方面說明了流程,流程是隨時間而改變,狀態是截取流程某個時間片。
例子:
操作當前狀態類:
public class Context {
private Weather weather;
public void setWeather(Weather weather) {
this.weather = weather;
}
public Weather getWeather() {
return this.weather;
}
public String weatherMessage() {
return weather.getWeather();
}
}
狀態接口:
public interface Weather {
String getWeather();
}
狀態實現類:
public class Sunshine implements Weather{
public String getWeather() {
return "陽光";
}
}
public class Rain implements Weather{
public String getWeather() {
return "下雨";
}
}
測試類:
public class Test {
public static void main(String[] args) {
Context ctx1 = new Context();
ctx1.setWeather(new Sunshine());
System.out.println(ctx1.weatherMessage());
System.out.println("===============");
ctx1.setWeather(new Rain());
System.out.println(ctx1.weatherMessage());
}
}
例子2:
public class Work {
private State current;
public Work(double hour,boolean finish){
current = new ForenoonState();
this.hour = hour;
this.finish = finish;
}
private double hour;
public double getHour() {
return hour;
}
public State getCurrent() {
return current;
}
public void setCurrent(State current) {
this.current = current;
}
private boolean finish;
public boolean isFinish() {
return finish;
}
public void writeProgram(){
current.writeProgram(this);
}
}
public interface State {
void writeProgram(Work work);
}
public class ForenoonState implements State {
@Override
public void writeProgram(Work work) {
if(work.getHour()<12){
System.out.println("工作時間");
}else {
work.setCurrent(new NoonState());
work.writeProgram();
}
}
}
public class NoonState implements State {
@Override
public void writeProgram(Work work) {
if(work.getHour()<13){
System.out.println("午睡");
}else {
work.setCurrent(new AfterNoonState());
work.writeProgram();
}
}
}
public class AfterNoonState implements State {
@Override
public void writeProgram(Work work) {
if(work.getHour()<17){
System.out.println("工作");
}else {
work.setCurrent(new EveningState());
work.writeProgram();
}
}
}
public class EveningState implements State {
@Override
public void writeProgram(Work work) {
if(work.isFinish()){
work.setCurrent(new RestState());
work.writeProgram();
}else {
if(work.getHour()<21){
System.out.println("加班");
}else {
work.setCurrent(new SleepState());
work.writeProgram();
}
}
}
}
public class SleepState implements State {
@Override
public void writeProgram(Work work) {
System.out.println("睡覺");
}
}