装饰模式——各国人的属性代码实现
实现一
public class main {
public static void main(String[] args) {
hignChinese hc=new hignChinese();
hc.setName("姚明");
richChinese rc=new richChinese();
rc.setName("马云");
hignrichChinese hrc=new hignrichChinese();
hrc.setName("Tom");
hc.desc();
rc.desc();
hrc.desc();
}
}
//业务操作接口
abstract class Person{
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name=name;
}
public abstract void desc();
}
//主体类:中国人
class Chinese extends Person{
public void desc() {
System.out.println(name+"是中国人");
}
}
//主体类:美国人
class American extends Person{
public void desc() {
System.out.println(name+"是美国人");
}
}
//扩展操作
class hignChinese extends Chinese{
public void desc() {
super.desc();
System.out.println("是hign人");
}
}
class richChinese extends Chinese{
public void desc() {
super.desc();
System.out.println("是rich人");
}
}
class hignrichChinese extends Chinese{
public void desc() {
super.desc();
System.out.println("是hign&rich人");
}
}
实现二:组合代替继承
public class main {
public static void main(String[] args) {
Chinese c=new Chinese();
c.setName("姚明");
hignChinese hc=new hignChinese(c);
hc.desc();
c.setName("马云");
richChinese rc=new richChinese(c);
rc.desc();
American a=new American();
a.setName("Tom");
hignrichAmerican hrc=new hignrichAmerican(a);
hrc.desc();
}
}
//业务操作接口
abstract class Person{
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name=name;
}
public abstract void desc();
}
//主体类:中国人
class Chinese extends Person{
public void desc() {
System.out.println(name+"是中国人");
}
}
//主体类:美国人
class American extends Person{
public void desc() {
System.out.println(name+"是美国人");
}
}
//扩展操作:组合代替继承
class hignChinese {
Chinese person;//组合代替继承
public void desc() {
person.desc();
System.out.println("是hign人");
}
public hignChinese(Chinese person) {
this.person=person;
}
}
class richChinese {
Chinese person;//组合代替继承
public void desc() {
person.desc();
System.out.println("是rich人");
}
public richChinese(Chinese person) {
this.person=person;
}
}
class hignrichChinese {
Chinese person;//组合代替继承
public void desc() {
person.desc();
System.out.println("是hign&rich人");
}
public hignrichChinese(Chinese person) {
this.person=person;
}
}
class hignAmerican {
American person;//组合代替继承
public void desc() {
person.desc();
System.out.println("是hign人");
}
public hignAmerican(American person) {
this.person=person;
}
}
class richAmerican {
American person;//组合代替继承
public void desc() {
person.desc();
System.out.println("是rich人");
}
public richAmerican(American person) {
this.person=person;
}
}
class hignrichAmerican{
American person;//组合代替继承
public void desc() {
person.desc();
System.out.println("是hign&rich人");
}
public hignrichAmerican(American person) {
this.person=person;
}
}
当一个变量的声明类型都是某个基类(Person)的子类(Chinese、American)的时候,就该将它声明为这个基类(Person),由于多态,可以使得它在未來(运行时)成为子类的对象。
实现三:基类代替子类
public class main {
public static void main(String[] args) {
Chinese c=new Chinese();
c.setName("姚明");
hignChinese hc=new hignChinese(c);
hc.desc();
c.setName("马云");
richChinese rc=new richChinese(c);
rc.desc();
American a=new American();
a.setName("Tom");
hignrichAmerican hrc=new hignrichAmerican(a);
hrc.desc();
}
}
//业务操作接口
abstract class Person{
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name=name;
}
public abstract void desc();
}
//主体类:中国人
class Chinese extends Person{
public void desc() {
System.out.println(name+"是中国人");
}
}
//主体类:美国人
class American extends Person{
public void desc() {
System.out.println(name+"是美国人");
}
}
//扩展操作:基类代替子类
class hignChinese {
Person person;//基类代替子类,消除编译时的依赖
public void desc() {
person.desc();
System.out.println("是hign人");
}
public hignChinese(Person person) {
this.person=person;
}
}
class richChinese {
Person person;//基类代替子类,消除编译时的依赖
public void desc() {
person.desc();
System.out.println("是rich人");
}
public richChinese(Person person) {
this.person=person;
}
}
class hignrichChinese {
Person person;//基类代替子类,消除编译时的依赖
public void desc() {
person.desc();
System.out.println("是hign&rich人");
}
public hignrichChinese(Person person) {
this.person=person;
}
}
class hignAmerican {
Person person;//基类代替子类,消除编译时的依赖
public void desc() {
person.desc();
System.out.println("是hign人");
}
public hignAmerican(Person person) {
this.person=person;
}
}
class richAmerican {
Person person;//基类代替子类,消除编译时的依赖
public void desc() {
person.desc();
System.out.println("是rich人");
}
public richAmerican(Person person) {
this.person=person;
}
}
class hignrichAmerican{
Person person;//基类代替子类,消除编译时的依赖
public void desc() {
person.desc();
System.out.println("是hign&rich人");
}
public hignrichAmerican(Person person) {
this.person=person;
}
}
实现四:消除重复
public class main {
public static void main(String[] args) {
Chinese c=new Chinese();
c.setName("姚明");
hignPerson hc=new hignPerson(c);
hc.desc();
c.setName("马云");
richPerson rc=new richPerson(c);
rc.desc();
American a=new American();
a.setName("Tom");
hignrichPerson hrc=new hignrichPerson(a);
hrc.desc();
}
}
//业务操作接口
abstract class Person{
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name=name;
}
public abstract void desc();
}
//主体类:中国人
class Chinese extends Person{
public void desc() {
System.out.println(name+"是中国人");
}
}
//主体类:美国人
class American extends Person{
public void desc() {
System.out.println(name+"是美国人");
}
}
//扩展操作:消除重复
class hignPerson {
Person person;//基类代替子类,消除编译时的依赖
public void desc() {
person.desc();
System.out.println("是hign人");
}
public hignPerson(Person person) {
this.person=person;
}
}
class richPerson {
Person person;//基类代替子类,消除编译时的依赖
public void desc() {
person.desc();
System.out.println("是rich人");
}
public richPerson(Person person) {
this.person=person;
}
}
class hignrichPerson {
Person person;//基类代替子类,消除编译时的依赖
public void desc() {
person.desc();
System.out.println("是hign&rich人");
}
public hignrichPerson(Person person) {
this.person=person;
}
}
发现问题: 为了保证从继承转组合以后的抽象接口函数public void desc()遵循接口规范, 即继承基类设置的抽象接口函数public void descO。还是需要通过继承来完善接规范, 不过只需要继承基类Persop
实现五:实现接口继承基类Person
public class main {
public static void main(String[] args) {
Chinese c = new Chinese();
c.setName("姚明");
hignPerson hc = new hignPerson(c);
hc.desc();
c.setName("马云");
richPerson rc = new richPerson(c);
rc.desc();
American a = new American();
a.setName("Tom");
hignrichPerson hrc = new hignrichPerson(a);
hrc.desc();
}
}
//业务操作接口
abstract class Person {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void desc();
}
//主体类:中国人
class Chinese extends Person {
public void desc() {
System.out.println(name + "是中国人");
}
}
//主体类:美国人
class American extends Person {
public void desc() {
System.out.println(name + "是美国人");
}
}
//扩展操作:实现接口继承基类Person
class hignPerson extends Person{
Person person;// 基类代替子类,消除编译时的依赖
public void desc() {//继承基类Person就能保证实现接口
person.desc();
System.out.println("是hign人");
}
public hignPerson(Person person) {
this.person = person;
}
}
class richPerson extends Person{
Person person;// 基类代替子类,消除编译时的依赖
public void desc() {
person.desc();
System.out.println("是rich人");
}
public richPerson(Person person) {
this.person = person;
}
}
class hignrichPerson extends Person{
Person person;// 基类代替子类,消除编译时的依赖
public void desc() {
person.desc();
System.out.println("是hign&rich人");
}
public hignrichPerson(Person person) {
this.person = person;
}
}
实现六:使用装饰模式<中间基类>
public class main {
public static void main(String[] args) {
Chinese c = new Chinese();
c.setName("姚明");
hignPerson hc = new hignPerson(c);
hc.desc();
c.setName("马云");
richPerson rc = new richPerson(c);
rc.desc();
American a = new American();
a.setName("Tom");
hignrichPerson hrc = new hignrichPerson(a);
hrc.desc();
hignPerson hp=new hignPerson(a);
richPerson rp=new richPerson(hp);
rp.desc();
}
}
//业务操作接口
abstract class Person {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void desc();
}
//中间类
abstract class DecoratorPerson extends Person {
Person person;// 以聚合的方式来支持未来多态的变化
public DecoratorPerson(Person person) {
this.person = person;
}
}
//主体类:中国人
class Chinese extends Person {
public void desc() {
System.out.println(name + "是中国人");
}
}
//主体类:美国人
class American extends Person {
public void desc() {
System.out.println(name + "是美国人");
}
}
//扩展操作:实现接口继承基类Person
class hignPerson extends DecoratorPerson {
public void desc() {
person.desc();
System.out.println("是hign人");
}
public hignPerson(Person person) {
super(person);
}
}
class richPerson extends DecoratorPerson {
public void desc() {
person.desc();
System.out.println("是rich人");
}
public richPerson(Person person) {
super(person);
}
}
class hignrichPerson extends DecoratorPerson {
public void desc() {
person.desc();
System.out.println("是hign&rich人");
}
public hignrichPerson(Person person) {
super(person);
}
}
装饰模式定义:
动态的给一个对象添加一些额外的职责,就增加功能来说,
装饰模式比生成子类(继承)更为灵洁(消除重复代码&减少子类个数)
装饰类的代码实现
public class main {
public static void main(String[] args) {
ConcreteComponent c=new ConcreteComponent();
ConcreteDecoratorA d1=new ConcreteDecoratorA();
d1.SetComponent(c);
//d1.Operation();
ConcreteDecoratorB d2=new ConcreteDecoratorB();
d2.SetComponent(d1);
d2.Operation();
}
}
//Component类
abstract class Component{
public abstract void Operation();
}
//ConcreteComponent类
class ConcreteComponent extends Component{
public void Operation() {
System.out.println("具体对象的操作");
}
}
//Decorator类
abstract class Decorator extends Component{
protected Component component;
public void SetComponent(Component component) {
this.component=component;
}
public void Operation() {
if(component!=null) {
component.Operation();
}
}
}
//ConcreteDecoratorA类
class ConcreteDecoratorA extends Decorator{
private String addedState;//独有的功能
public void Operation() {
super.Operation();
addedState="New State";
System.out.println("具体装饰对象A的操作");
}
}
//ConcreteDecoratorB类
class ConcreteDecoratorB extends Decorator{
public void Operation() {
super.Operation();
addBehavior();
System.out.println("具体装饰对象B的操作");
}
private void addBehavior() {
System.out.println("AddedBehavior Operation");
}
}
通过采用组合而非继承的手法,Decorator模式实现了在运行时动态扩展对象功能的能力,而且可以根据需要扩展多个功能。避免了使用继承带来的“灵活性差”和“多子类衍生问题”。
Decorator类在接口上表现为is-a Component的继承关系,
即Decorator类继承了Component类所具有的接口。
但在实现上又表现为has-a Component的组合关系,
即Decorator类又使用了Component类。
若是程序中一个类的父类和他的字段类是同一个类的,
那么它有极大的几率是Decorator模式。因为一般继承就不组合,组合就不继承.
而Decorator模式旦的继承是为了接口的规范,组合是为了将来支持具体实现类:
is a Component 并三 has a Component:
is a Component是为了接口的统一性(继承) 。
has a Component 是为了充分利用多态性, 来消除没必妥的派生类。(组合)
既继承又组合是装饰模式强大,巧妙的地方。
Decorator模式的目的并非解决“多子类衍生的多继承”问题,
Decorator模式应用的要点在于解决“主体类在多个方向上的扩展功能” 是为“装饰”的含义。
装饰模式的优点:
- 装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性
- 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。
缺点:
- 会产生很多细粒度的对象。
以上部分摘取自朱红梅老师2020年5月的课件