寫一個簡單的角色裝扮代碼:
public class Program {
public static void main(String[] args) {
Person person = new Person("小菜");
System.out.println("第一種裝扮");
person.wearTShirts();
person.wearBigTrouser();
System.out.println("第二種裝扮");
person.wearSuits();
person.wearLeaherShoes();
}
}
class Person{
private String name;
public Person(String name) {
this.name = name;
}
public void wearTShirts(){
System.out.println("大T恤 ");
}
public void wearBigTrouser(){
System.out.println("垮褲");
}
public void wearSuits(){
System.out.println("西裝");
}
public void wearLeaherShoes(){
System.out.println("穿皮鞋");
}
}
問題來了:如果我們增加一個裝飾,就要修改很多代碼,上面的代碼不符合我們的開發閉合原則:面對需求,對程序的改動是通過增加新代碼進行的,而不是更改現有的代碼。
public class Program {
public static void main(String[] args) {
Person person = new Person("小菜");
TShirtsFinery tShirts = new TShirtsFinery();
BigTrouserFinery bigTrouser = new BigTrouserFinery();
System.out.println("第一種裝扮");
tShirts.show();
bigTrouser.show();
SuitsFinery suits = new SuitsFinery();
LeaherShoesFinery leaherShoes = new LeaherShoesFinery();
System.out.println("第二種裝扮");
suits.show();
leaherShoes.show();
}
}
class Person {
private String name;
public Person(String name){
this.name = name;
}
}
abstract class Finery{
public abstract void show();
}
class TShirtsFinery extends Finery {
@Override
public void show() {
System.out.println("大T恤 ");
}
}
class BigTrouserFinery extends Finery {
@Override
public void show() {
System.out.println("垮褲 ");
}
}
class SuitsFinery extends Finery {
@Override
public void show() {
System.out.println("西裝 ");
}
}
class LeaherShoesFinery extends Finery {
@Override
public void show() {
System.out.println("穿皮鞋 ");
}
}
問題來了:上面的代碼不夠封閉,我們想要其中一種裝扮,就要暴露很多方法,每個裝飾相互間的聯繫應該封裝起來,我們要採用裝飾設計模式。
public class Program {
public static void main(String[] args) {
Person person = new Person("小菜");
TShirtsFinery tShirts = new TShirtsFinery();
BigTrouserFinery bigTrouser = new BigTrouserFinery();
System.out.println("第一種裝扮");
tShirts.decorate(person);
bigTrouser.decorate(tShirts);
bigTrouser.show();
SuitsFinery suits = new SuitsFinery();
LeaherShoesFinery leaherShoes = new LeaherShoesFinery();
System.out.println("第二種裝扮");
suits.decorate(person);
leaherShoes.decorate(suits);
leaherShoes.show();
}
}
class Person {
private String name;
public Person(){ }
public Person(String name){
this.name = name;
}
public void show(){
System.out.println("裝扮的" + name);
}
}
class Finery extends Person{
protected Person component;
public void decorate(Person component) {
this.component = component;
}
@Override
public void show() {
if (component != null) {
component.show();
}
}
}
class TShirtsFinery extends Finery {
@Override
public void show() {
System.out.println("大T恤 ");
super.show();
}
}
class BigTrouserFinery extends Finery {
@Override
public void show() {
System.out.println("垮褲 ");
super.show();
}
}
class SuitsFinery extends Finery {
@Override
public void show() {
System.out.println("西裝 ");
super.show();
}
}
class LeaherShoesFinery extends Finery {
@Override
public void show() {
System.out.println("穿皮鞋 ");
super.show();
}
}
個人總結;裝飾模式是爲已有功能動態地添加更多功能的一種方式。什麼時候用呢?當系統需要新功能的時候,是向舊的類中添加新的代碼。這些新加的代碼通常裝飾了原有類的核心職責或主要行爲。