欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

类抽象的设计问题

程序员文章站 2024-02-21 12:46:40
...
    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
        }
    }

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

  • 写法一

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

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

       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();
           }
       }
       

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

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

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

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

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

回复内容:

    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
        }
    }

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

  • 写法一

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

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

       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();
           }
       }
       

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

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

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

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

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

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

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

感觉不出来是因为没疼过

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

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

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