类抽象的设计问题

WBOY
WBOYオリジナル
2016-06-06 20:23:511214ブラウズ

<code>    public interface A{
       void a();
    }
    
    public abstract class B{
        protected abstract boolean lockA();
        
        public void a(){
            if(lockA()){
                do();
            }
        }
        
        protected abstract void do();
    }
    
    public class C extends B implements A{
        public boolean lockA(){
            return true;   
        }
        
        public void do(){
            //TODO one
        }
    }</code>

这个时候需要一个新的类D,类D的lockA的规则是和C是一样的。所以在这里就出现以下几种写法:

  • 写法一

    <code>   public class D extends B implements A{
           private C c = new C();
           
            public boolean lockA(){
                 c.lockA();
           }
           
           public void do(){
               //TODO two
           }
       }</code>
  • 写法二

    <code>   public class D extends C implements A{
            public boolean lockA(){
                 super.lockA();
           }
           
           public void do(){
               //TODO two
           }
       }
       </code>
  • 写法三

    <code>   public interface Lock{
           boolean lockA();
       }
       
       public interface DO{
           void do();
       }
       
       public class C extends B implements A{
           private Lock lock;
           
           private DO do;
       
           public boolean lockA(){
               return lock.lockA();   
           }
           
           public void do(){
               do.do();
           }
       }
       </code>

    写法一通过把类C组合进类D,然后简介调用C的方法lockA()

写法二通过继承的方法来复用lockA()
写法三,通过吧Lock和Do做一层抽象,然后通过组合的方式来调用,这个方法的灵活度和可扩展性很高。也是我比较喜欢的做法。

如上述方法一和方法二,在我看来其实也未必不可。我唯一觉得方法三比方法一,二的优势是在类的层次上设计上更加合理,因为C,D同为A的子集,如果还存在依赖关系就感觉很不合理。

最近自己陷入了一个怪圈,我一直在思考到底什么样子的代码才算是好的代码。很多时候我都凭着自己的感觉去选择编码的方式,比如上述问题,我会凭我的感觉去选择方法三。还有很多很多情况,我会凭自己的感觉去判断一段代码的好坏,但是我有的时候会自己问自己,或者让我举一个反例来说明现在的方法不好,我会想很长时间才能想出来,甚至是想不出来,因为很多时候我发现自己是根据感觉去判断一段代码是否优雅的。。。。

希望有经验的老前辈可以指教一二,谢谢。

回复内容:

<code>    public interface A{
       void a();
    }
    
    public abstract class B{
        protected abstract boolean lockA();
        
        public void a(){
            if(lockA()){
                do();
            }
        }
        
        protected abstract void do();
    }
    
    public class C extends B implements A{
        public boolean lockA(){
            return true;   
        }
        
        public void do(){
            //TODO one
        }
    }</code>

这个时候需要一个新的类D,类D的lockA的规则是和C是一样的。所以在这里就出现以下几种写法:

  • 写法一

    <code>   public class D extends B implements A{
           private C c = new C();
           
            public boolean lockA(){
                 c.lockA();
           }
           
           public void do(){
               //TODO two
           }
       }</code>
  • 写法二

    <code>   public class D extends C implements A{
            public boolean lockA(){
                 super.lockA();
           }
           
           public void do(){
               //TODO two
           }
       }
       </code>
  • 写法三

    <code>   public interface Lock{
           boolean lockA();
       }
       
       public interface DO{
           void do();
       }
       
       public class C extends B implements A{
           private Lock lock;
           
           private DO do;
       
           public boolean lockA(){
               return lock.lockA();   
           }
           
           public void do(){
               do.do();
           }
       }
       </code>

    写法一通过把类C组合进类D,然后简介调用C的方法lockA()

写法二通过继承的方法来复用lockA()
写法三,通过吧Lock和Do做一层抽象,然后通过组合的方式来调用,这个方法的灵活度和可扩展性很高。也是我比较喜欢的做法。

如上述方法一和方法二,在我看来其实也未必不可。我唯一觉得方法三比方法一,二的优势是在类的层次上设计上更加合理,因为C,D同为A的子集,如果还存在依赖关系就感觉很不合理。

最近自己陷入了一个怪圈,我一直在思考到底什么样子的代码才算是好的代码。很多时候我都凭着自己的感觉去选择编码的方式,比如上述问题,我会凭我的感觉去选择方法三。还有很多很多情况,我会凭自己的感觉去判断一段代码的好坏,但是我有的时候会自己问自己,或者让我举一个反例来说明现在的方法不好,我会想很长时间才能想出来,甚至是想不出来,因为很多时候我发现自己是根据感觉去判断一段代码是否优雅的。。。。

希望有经验的老前辈可以指教一二,谢谢。

如果你是想考量你所列举的几种方法的优劣,我想最好还是套到实际的情况中去决定。所谓设计模式,只是对常用编程思路的一个抽象而已,设计模式之间没有好坏之分,只有谁更适合实际的情况。所以单纯比较几种设计模式,并不能分析得非常到位。

另外,要实现的上述的这个思路,我想你可以尝试一下php的 trait ,我想它比上述的方法需要书写的代码更少,兼容的场景更多。

感觉不出来是因为没疼过

这种时候随便挑一种写完再说

等累积了一定的代码量,来来回回修改迭代了若干版本之后,下次面对类似的情况就有感觉了

“上次我那样那样做,后来代码变成了一坨没法维护的垃圾,这次得从最开始就避免”

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。