package com.wfl.designmode;
/**
* 使用接口设计一个抽象功能方法,让具体类去实现接口中的不同方法;
*
*/
/*
需求:模拟鸭子叫、游泳、展示自己的外观、满足鸭子会飞,但是有些鸭子,比如橡胶鸭不能飞,只会咯吱咯吱叫
* 分析:实现接口的方式是首先想到的,可以让所有不同的鸭子都会叫、游泳、展示自身外观
*
* 解决方案1:那么最简单的方式就是在接口中添加flay方法,并且方所有的实现类去实现它,橡胶鸭子要覆盖这个方法设置为不能飞,quack方法设置为咯吱咯吱
* 缺点:上面好像可以实现,但是不利于扩展,每当要增加其他鸭子,都要被迫检查可能要覆盖fly和quark(),比如诱饵鸭子不会飞、不会叫。。。
* 总结:单纯使用实现+接口覆盖这种方式实现多种不同类型的实例是不友好的,加大了代码量,不好维护
*/
public class FirstMode {
}
/**
* 第一步:定义鸭子接口,所有的鸭子实现类实现这个接口
*/
interface duckInterface{
/**
* 鸭子叫
*/
void quack();
/**
* 鸭子游泳
*/
void swim();
/**
* 鸭子展示自己的外观
*/
void display();
}
/**
* 第二步:实现具体的鸭子类型
*/
class MallardDuck implements duckInterface{
@Override
public void quack() {
System.out.println("MallardDuck quack");
}
@Override
public void swim() {
System.out.println("MallardDuck swim");
}
@Override
public void display() {
System.out.println("MallardDuck display");
}
}
/**
* 第二步:实现具体的鸭子类型
* ... 可以创建N多个鸭子类,这些鸭子都会游泳、叫、特技
*/
class RedheadDuck implements duckInterface{
@Override
public void quack() {
System.out.println("RedheadDuck quack");
}
@Override
public void swim() {
System.out.println("RedheadDuck swim");
}
@Override
public void display() {
System.out.println("RedheadDuck display");
}
}
/* 解决方案2:将方法归类,一种是鸭子的公共的特征方法,比如display、swim;另外一种是特殊的方法,比如flay、quack;让鸭子去根据自身的情况去实现这两种接口
* 比如橡胶鸭子就不用实现flay方法所在的接口,
* 缺点:如果需要100个鸭子实体类,所有的鸭子类都去实现公共的接口,但是有许多鸭子实体类还需要稍微修改一下flay方法,代码无法复用。。。
* 总结:继承或实现的方式不能很好地解决问题,应为鸭子的行为在类中千变万化,让所有的鸭子都有这些行为是不恰当的。
*/
/**
* 公共方法,鸭子都有外部特征display,都会游泳
*/
class Duck{
void swim(){
System.out.println("HolledDuck swim");
}
void display(){
System.out.println("HolledDuck red head");
}
}
/**
* 只有部分鸭子会飞、会叫
*/
interface Flayable{
void flay();
}
interface Quackable{
void quack();
}
/**
* 100多种鸭子,都要重写下面的方法
*/
class HolledDuck extends Duck implements Flayable,Quackable{
/**
* 需要修改flay方法
*/
@Override
public void flay() {
System.out.println("HolledDuck flay");
}
/**
* 需要修改quack方法
*/
@Override
public void quack() {
System.out.println("HolledDuck quack");
}
}
/*
* 设计原则1:找出应用中可能需要变化的地方,把它们独立(抽取)出来,不要和那些不需要变化的代码混合在一起。
*
* 使用设计模式的方案:鸭子类不再实现flayable等这些接口,我们设计专门的类来实现flayable接口,这种专门的类称为行为类
* 以前的鸭子类要实现行为类的功能,这种方式都依赖于子类的实现,被绑的死死地,
* 鸭子的子类直接使用行为类,组合的方式,
* */
interface FlayBehavior{
void flay();
}
/**
* 实现了所有有翅膀的鸭子的飞行
*/
class FlayWithWings implements FlayBehavior{
@Override
public void flay() {
System.out.println("鸭子的飞行");
}
}
/**
* 实现所有不会飞的鸭子的动作
*/
class FlayNoWay implements FlayBehavior{
@Override
public void flay() {
System.out.println("什么都不做,不会飞");
}
}
interface QuackBehavior{
void quack();
}
/**
* 实现真正的鸭子呱呱叫
*/
class Quack implements QuackBehavior{
@Override
public void quack() {
System.out.println("鸭子呱呱叫");
}
}
/**
* 实现了橡皮鸭子吱吱叫
*/
class Squeak implements QuackBehavior{
@Override
public void quack() {
System.out.println("橡皮鸭子吱吱叫");
}
}
/**
* 实现了不吭声的鸭子
*/
class MutaQuack implements QuackBehavior{
@Override
public void quack() {
System.out.println("什么都不做,不会叫");
}
}
/**
* 优点:1.让飞行和呱呱叫的动作行为类被其他对象复用,这些行为与鸭子本身类无关
* 2.当新增一些行为,不会影响到飞行和呱呱叫等,也不会影响到使用飞行类的鸭子类
* 3。有了继承的复用好处,但是没有继承所带来的报复
*
* 具体实现:1.在Duck类中加入两个接口类型的实例变量,每个鸭子都会动态的设置这些变量,在运行时引用正确的行为类型
*/
class DDuck{
public FlayBehavior flayBehavior;
public QuackBehavior quackBehavior;
/**
* 鸭子对象不亲自处理呱呱叫的行为,而是委托给quackBehavior引用的对象
* 想要呱呱叫就传Quack子类,想要吱吱叫就传Squeak,
* 我们不用知道如何实现,只需要知道对象知道要怎样叫就行了
*/
public void performQuack(){
quackBehavior.quack();
}
public void performFlay(){
flayBehavior.flay();
}
/**
* !!!在鸭子子类中通过设定方法来设置鸭子的行为,而不是构造器内部实例化
*
*/
public void setFlayBehavior(FlayBehavior fb){
flayBehavior = fb;
}
public void setQuackBehavior(QuackBehavior qb){
quackBehavior = qb;
}
}
/*
* 如何设置flayBehavior和quackBehavior
* 1.使用构造器
* 2.使用setter方法
* */
class MallardDDuck extends DDuck{
/**
* 应为MallardDDuck继承了DDuck,拥有两个实例变量
* 这里是默认的行为
*/
public MallardDDuck(){
flayBehavior = new FlayWithWings();
quackBehavior = new Quack();
}
/**
* 鸭子的公共方法
*/
public void display(){
System.out.println("real Mallard Duck");
}
}
/**
测试类
*/
class testDuck{
public static void main(String[] args) {
DDuck mallred = new MallardDDuck();
mallred.setFlayBehavior(new FlayNoWay());
mallred.setQuackBehavior(new MutaQuack());
mallred.performFlay();
mallred.performQuack();
}
}
设计模式(一)继承+组合
最新推荐文章于 2024-02-19 10:39:27 发布