Improve class design – there is a function that should not be callable

Solution for Improve class design – there is a function that should not be callable
is Given Below:

Today, I thought to myself that I would quickly create a descriptive example of the access modifiers Public, Private and Protected for someone, taken from real life.
The following example: A caretaker can spend a budget provided by the landlord himself without having to call for every little thing. For moderate repairs, however, he must call the landlord or the landlord’s son and ask for it. The son then knows what money he may spend. Big repairs can only be decided by the landlord (not the son).
I transferred that to source code.

I want to improve the class design, because I can still write Tom.DecideMajorRepair (" ") in Form1.vb, which should not work and what I find unclean.

Form1.vb

Public NotInheritable Class FormMain
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim Hans As New ClassVermieter ' Landlord
        Dim Tom As New ClassVermietersSohn ' Landlord's son

        'easily accessible
        Dim MyBudget As UInt16 = Hans.Caretakers_budget_for_minor_repairs - 200US

        Dim Budget_received_1 As UInt16 = Hans.DecideModerateRepair("Unfortunately, the heating is broken!")

        ' Call son because father didn't answer the phone (or whatever). He can also decide that (protected).
        ' I still have to ask permission from one of them.
        Dim Budget_received_2 As UInt16 = Tom.DecideForHimselfModerateRepair("Unfortunately, the heating is broken!")

        ' Son cannot decide a major repair - only the landlord.
        Dim Budget_received_3 As UInt16 = Tom.DecideForHimselfLargeRepair("Unfortunately, the heating is broken!")
        Dim Budget_received_4 As UInt16 = Hans.DecideMajorRepair("Unfortunately, the heating is broken!")
    End Sub
End Class

ClassVermieter.vb (landlord)

Public Class ClassVermieter
    
    ''' <summary>
    ''' per month
    ''' </summary>
    Public Property Caretakers_budget_for_minor_repairs As UInt16 = 500US

    '–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
    Protected Property Permission_for_medium_repairs As UShort
    '–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

    Private Permission_for_large_repairs As UInt16


    'answers the phone call from the caretaker
    Public Function DecideModerateRepair(ByVal Message_from_the_caretaker As String) As UInt16
        Permission_for_medium_repairs = 1000US
        Return Permission_for_medium_repairs
    End Function

    'answers the phone call from the caretaker
    Public Function DecideMajorRepair(ByVal Message_from_the_caretaker As String) As UInt16
        Permission_for_large_repairs = 5000US
        Return Permission_for_large_repairs
    End Function
End Class

ClassVermietersSohn.vb (Landlord’s son)

Public Class ClassVermietersSohn : Inherits ClassVermieter
    
    Private ReadOnly zero As UInt16 = 0US

    'answers the phone call from the caretaker
    'He can decide for himself whether a moderate repair should be carried out.
    Public Function DecideForHimselfModerateRepair(ByVal Message_from_the_caretaker As String) As UInt16
        Permission_for_medium_repairs = 1000US
        Return Permission_for_medium_repairs
    End Function

    'answers the phone call from the caretaker
    Public Function DecideForHimselfLargeRepair(ByVal Message_from_the_caretaker As String) As UInt16
        Return zero 'Well, that was nothing, because the son cannot spend (not see) the large amounts! 
    End Function
End Class

This code is kept elementarily. I am aware that money is not handled with Uint16. The first thing I wanted to do was build the structure.
The difficulty that kept me from solving it myself was that I didn’t know how to change the Get and Set without an error message.

In terms of the domain, I would not put the burden of knowing “whom” to ask on the caretaker. Ideally, the caretaker should have a single point of contact which can internally route the request and return true/false.

One design decision is how to parameterise the repair request.

This is most easily done by using an enum RepairTypes with a list of possible repair requests.

Then, I would have an interface “RepairApprover” with a method “boolean request(RepairType rt) throws NotSupportedException” – the exception would be used to “go up the chain”

Next, I would either have a LandlordAssistant class implement RepairApprover,

and a separate Landlord class also implementing RepairApprover.

Internally, the Landlord class would have a private field for LandlordAssistant so that it could reuse the code for minor and medium repairs.

I would then make a “ApprovalHierarchy” class with method “RepairApproval getMyManager()”

I would inject the LandlordAssistant as a “RepairApprover” instance into the Caretaker class constructor.

Internally, the LandlordAssistant.request method would try to respond to a small or medium request. If the request type is MAJOR, it would call ApprovalHierarchy.getMyManager(this).request(..) thus passing the request up the chain.

Hope that helps?